C - Guarantee condvars are ready for signalling

时光毁灭记忆、已成空白 提交于 2019-12-08 06:19:25

I could always create a status boolean that is set within the corresponding mutex, but I cannot atomically do both the set and the wait operation in one instruction, so far as I know.

That's the right way to do it -- you can do a set and wait operation atomically, because of the way condition variables interact with mutexes. When you do a pthread_cond_wait() operation, you must have the mutex that you pass in be locked. If you correspondingly have that same mutex locked when you do a pthread_cond_signal(), the waiting thread doesn't wake up until the signalling thread unlocks the mutex.

So, the following code would do what you want:

// Flag indicating if the worker thread is waiting or not
bool waiting = false;
...

// Worker thread code
... do stuff ...
while (!condition_is_not_satisfied())
{
    pthread_mutex_lock(&mutex);
    waiting = true;
    pthread_cond_wait(&cond, &mutex);
    waiting = false;
    pthread_mutex_unlock(&mutex);
}
...

// Signalling thread code
pthread_mutex_lock(&mutex);
if (waiting)
{
    // Worker thread is waiting -- signal it to wake up
    pthread_cond_signal(&cond);
}
else
{
    // Worker thread has not yet entered the wait state -- do something else
}
pthread_mutex_unlock(&mutex);

A condition variable should always be paired with a mutex-protected predicate. In this case, your predicate can just be a simple flag: in the worker thread, it would look like:

pthread_mutex_lock(&mMutex);
while (!woken)
    pthread_cond_wait(&mMutex, &condVar);
pthread_mutex_unlock(&mMutex);

In the manager thread, it would look like:

pthread_mutex_lock(&mMutex);
woken = 1;
pthread_cond_signal(&condVar);
pthread_mutex_unlock(&mMutex);

Here, if the manager thread acquires the mutex first, then by the time the worker acquires the mutex the flag will be set, and it won't wait at all; if the worker acquires the mutex first, then manager won't be able to acquire the mutex and set the flag until the worker has been held at the pthread_cond_wait.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!