与SDL线程库进行线程同步

时间:2016-02-12 13:00:23

标签: c++ multithreading sdl

我正在尝试使用SDL2的线程库为C ++中的多线程编写一个线程安全的任务队列。

在所有线程上运行的线程函数如下:

int threadFunc(void * pData)
{
    ThreadData* data = (ThreadData*)pData;
    SDLTaskManager* pool = data->pool;
    Task* task = nullptr;
    while (true)
    {
        SDL_LockMutex(pool->mLock);
        while (!pool->mRunning && pool->mCurrentTasks.empty())
        {
            //mutex is unlocked, then locked again when signal received
            SDL_CondWait(pool->mConditionFlag, pool->mLock);
            if (pool->mShuttingDown)
                return 0;
        }
        //mutex is locked at this stage so no other threads can alter contents of deque
        //code inside if block should not be executed if deque is empty
        if (!pool->mCurrentTasks.empty())
        {
            /*out of range error here*/
            task = pool->mCurrentTasks.front();
            pool->mCurrentTasks.pop_front();
        }

        if (task != nullptr)
        {
            pool->notifyThreadWorking(true);
            data->taskCount++;
        }
        else
        {
            pool->stop();
            SDL_UnlockMutex(pool->mLock);
            continue;
        }
        SDL_UnlockMutex(pool->mLock);
        task->execute();
        SDL_LockMutex(pool->mLock);
        pool->notifyThreadWorking(false);
        pool->mCompleteTasks.push_back(task);
        SDL_UnlockMutex(pool->mLock);
        task = nullptr;
    }
    return 0;
}

正如您所看到的,根据代码中的注释,if块中出现超出范围的错误,其中deque为空。但是,在那里进行检查以确保仅在deque不为空时才执行代码。互斥锁被SDL_CondWait锁定,因此没有其他线程能够对双端队列进行更改,直到该互斥锁再次解锁为止。

生产者代码如下:

SDL_LockMutex(pool->mLock);
for (int i = 0; i < numTasks; i++)
{
    pool->mCurrentTasks.push_back(new Task());
}
pool->mRunning = true;
SDL_CondBroadcast(pool->mConditionFlag);
SDL_UnlockMutex(pool->mLock);

if块中的代码正在被执行的事实表明,在评估if (!pool->mCurrentTasks.empty())时,deque有成员数据,但在到达task = pool->mCurrentTasks.front();时却没有。我对mutex的理解'这不应该是可能的。怎么会这样?

0 个答案:

没有答案