将作业添加到线程池时出现死锁

时间:2016-03-07 13:15:42

标签: c++ multithreading threadpool

在向线程池添加作业时,我的游戏冻结有问题。我一直在查看我的代码,但找不到问题。

我的线程池主要是标准的,包含要执行的作业列表。工作线程从此列表中获取作业并执行它们。然后他们发出信号说他们完成了工作(这样我就可以等待所有工作完成(不仅仅是从工作列表中启动/删除)而不加入线程(我也想在下一帧使用它们)。)。 p>

void ThreadPool::Add(std::function<void()> job) {
    {
        std::unique_lock<std::mutex> lock(mJobMutex);
        mJobs.push(job);
        ++mUnfinishedJobs;
    }

    mJobCondition.notify_one();
}

void Worker::Execute() {
    std::function<void()> job;
    while (true) {
        {
            std::unique_lock<std::mutex> lock(mThreadPool.mJobMutex);

            while (!mThreadPool.mStop && mThreadPool.mJobs.empty()) {
                // Wait for new job to become available.
                mThreadPool.mJobCondition.wait(lock);
            }

            if (mThreadPool.mStop)
                return;

            // Get next job.
            job = mThreadPool.mJobs.front();
            mThreadPool.mJobs.pop();
        }

        // Perform the job.
        job();

        // Signal that we finished the job.
        {
            std::unique_lock<std::mutex> lock(mThreadPool.mJobMutex);
            --mThreadPool.mUnfinishedJobs;
        }
        mThreadPool.mFinishedCondition.notify_all();
    }
}

通过一些日志记录,我设法将其归结为ThreadPool :: Add中的mJobCondition.notify_one()。我在该声明之前和之后放置了一些日志记录,它总是挂在那里。这对我来说很奇怪。当然,notify_one可能会错过等待它的线程,但如果确实如此,它应该什么都不做。对我来说,它会冻结在那条线上似乎很奇怪。

如果问题是我错误地锁定并且线程池和工作线程同时访问内存应该不会崩溃和刻录而不是冻结?

我在使用MinGW的Windows上。

我在线程池中也有一个Wait和Stop方法(这是mUnfinishedJobs变量的用法)但我没有包含它们,因为我知道在执行Add时它会冻结。

如果您需要更多上下文,

Here是完整的线程代码。

我知道我可能会使用一些为我做线程池的线程库,但我想知道它是如何完成的。

0 个答案:

没有答案