Многопоточная система задач не выполняет итерацию списка

Ладно, это немного не подходит для стека, но я постараюсь сделать его как можно короче.

Я получил поток, который берет задачи из списка и выполняет их. Просто как это (Рабочий класс имеет свой собственный поток и запускает doTask m_thread(&Worker::doTask, this)):

void Worker::doTask()
{
while (m_running)
{
auto task = m_tasks.pop_front();
task->execute();
if (task->isContinuous())
m_tasks.push_pack(task);
}
}

Сам список / должен быть потокобезопасным:
Заголовок:

class TaskQueue
{
public:
void push_pack(std::shared_ptr<Task> t);
std::shared_ptr<Task> pop_front();
private:
std::list<std::shared_ptr<Task>> m_tasks;
std::condition_variable m_cond;
std::mutex m_mutex;
void TaskQueue::push_pack(std::shared_ptr<Task> t)
}

Значения важной части:

void TaskQueue::push_pack(std::shared_ptr<Task> t)
{
m_tasks.push_back(t);
//notify that there is one more task, so one thread can work now
m_cond.notify_one();
}

std::shared_ptr<Task> TaskQueue::pop_front()
{
//regular lock so noone else acces this area now
std::unique_lock<std::mutex> lock(m_mutex);
while (m_tasks.size() == 0)
m_cond.wait(lock);

auto task = m_tasks.front();
m_tasks.pop_front();
return task;
}

И последнее, но не менее важное:

class Task
{
public:
virtual ~Task()
{
}
virtual void execute() = 0;
virtual bool isContinuous()
{
return false;
};
};

Так что, если я попытаюсь добавить эту задачу:

class NetworkRequestTask:public Task
{
public:
NetworkRequestTask(TaskQueue &q);
~NetworkRequestTask();

void execute() override;
bool isContinuous() override;
private:
TaskQueue &m_tasks;
};

Impl:

NetworkRequestTask::NetworkRequestTask(TaskQueue& q): m_tasks(q)
{
}

NetworkRequestTask::~NetworkRequestTask()
{
}

void NetworkRequestTask::execute()
{
while(dosomething)
{
//do something here
}
}

bool NetworkRequestTask::isContinuous()
{
return true;
}

Главный:

int main(int argc, char* argv[])
{
TaskQueue tasks;
tasks.push_pack(std::make_shared<NetworkRequestTask>(tasks));
}

он попадает в плохое состояние:

Expression: list iterator not derefercable

Я сбит с толку. Это происходит только в том случае, если я переопределяю Continouse, и это происходит только при выполнении этой задачи. Если я добавлю очередь в другую задачу Continouse в качестве ссылки, она не попадет в это плохое состояние.

Так что здесь происходит не так и важно, что я сделал не так?


Что касается комментариев, я уже пытался заблокировать метод push_back, который ничего не изменил в поведении. (Вы можете обменять его на обычный мьютекс, это не имеет значения.)

void TaskQueue::push_pack(std::shared_ptr<Task> t)
{
std::lock_guard<SpinLock> lock(m_spin);
m_tasks.push_back(t);
//notify that there is one more task, so one thread can work now
m_cond.notify_one();
}

0

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]