Ç - 担保条件变量已经准备好信号 [英] C - Guarantee condvars are ready for signalling

查看:109
本文介绍了Ç - 担保条件变量已经准备好信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的应用程序,与不同的硬件接口。对于每个硬件的,我生成一个的pthread_t 针对独特的监视功能,一共有6个线程:1,管理线程,和5个工作线程

每个线程都有一个共同的初始化程序在那里等待管理线程通过将其唤醒:

 的pthread_mutex_lock(安培; mMutex);
调用pthread_cond_wait(安培; mMutex,&安培; condVar);
调用pthread_mutex_lock(安培; mMutex);

然后,主线程通过信令它们一次一个唤醒所有线程

 调用pthread_cond_wait(安培; mMutex1,&安培; condVar1);
调用pthread_cond_wait(安培; mMutex2,&安培; condVar2);
...
调用pthread_cond_wait(安培; mMutex5,&安培; condVar5);

在code实际工作很好,但是这是因为我很幸运与时机。有远程,但存在的机会,当主/管理线程的问题调用pthread_cond_signal ,该线程尚未完成初始化。我需要找到一种方法来保证每一个条件变量已通过其各自的工作线程上做了一个电话。

我总是可以创建一个设置相应的互斥体中的地位布尔,但我不能原子一举​​两得的设置在一个指令操作,所以据我所知。我也可以利用一个 pthread_barrier_t ,但只是保证了所有线程都使得前一个或两个指令各自的通话。

是否有被某些一个尝试和真正的方法是,已经调用,或者我需要聘请的计时等待循环的一些方法/检查?

感谢您。


解决方案

  

我总是可以创建一个设置相应的互斥体中的地位布尔,但我不能做原子都设置在一个指令等待操作,只要我知道了。


这是应该做的正确方法 - 你的可以的做一套,等待操作原子,由于道路条件变量与互斥相互作用。当你做了调用pthread_cond_wait()的操作,你的必须的具有与您传递的互斥锁定。如果您有相应的,当你做同一个互斥锁定的调用pthread_cond_signal(),等待的线程不醒来,直到信令线程释放互斥锁。

因此​​,下面code会做你想要什么:

  //标志指示是否工作线程正在等待或不
布尔等待= FALSE;
...//工作线程code
... 做东西 ...
而(!condition_is_not_satisfied())
{
    调用pthread_mutex_lock(安培;互斥);
    等待= TRUE;
    调用pthread_cond_wait(安培; COND,和放大器;互斥);
    等待= FALSE;
    调用pthread_mutex_unlock(安培;互斥);
}
...//信令线程code
调用pthread_mutex_lock(安培;互斥);
如果(等待)
{
    //工作者线程处于等待 - 信号,它唤醒
    调用pthread_cond_signal(安培; COND);
}
其他
{
    //工作线程尚未进入等待状态 - 做别的事情
}
调用pthread_mutex_unlock(安培;互斥);

I have a simple application that interfaces with different pieces of hardware. For each piece of hardware, I spawn a pthread_t against a unique monitor function, for a total of 6 threads: 1 manager thread, and 5 worker threads.

Each thread has a common initialization routine where it waits for the manager thread to wake it up via:

pthread_mutex_lock(&mMutex);
pthread_cond_wait(&mMutex, &condVar);
pthread_mutex_lock(&mMutex);

The main thread then wakes up all of the threads by signalling them one at a time:

pthread_cond_wait(&mMutex1, &condVar1);
pthread_cond_wait(&mMutex2, &condVar2);
...
pthread_cond_wait(&mMutex5, &condVar5);

The code actually works fine, but this is because I am lucky with the timing. There is the remote but existent chance that when the main/manager thread issues pthread_cond_signal, that the thread is not yet done initialization. I need to find a way to guarantee that each and every condition variable has had a wait call made on it by its respective worker thread.

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. I could also make use of a pthread_barrier_t, but that just guarantees all the threads are one or two instructions before making their respective wait calls.

Is there a tried-and-true method of being certain that the wait call has been made, or do I need to employ some means of timed wait looping/checking?

Thank you.

解决方案

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);

这篇关于Ç - 担保条件变量已经准备好信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆