在我的程序中,有一部分代码等待从代码的其他部分唤醒:
这是睡眠的部分:
void flush2device(int task_id) {
if (pthread_mutex_lock(&id2cvLock) != SUCCESS) {
cerr << "system error - exiting!!!\n";
exit(1);
}
map<int,pthread_cond_t*>::iterator it;
it = id2cv.find(task_id);
if(it == id2cv.end()){
if (pthread_mutex_unlock(&id2cvLock) != SUCCESS) {
cerr << "system error\n UNLOCKING MUTEX flush2device\n";
exit(1);
}
return;
}
cout << "Waiting for CV signal" <<endl;
if(pthread_cond_wait(it->second, &id2cvLock)!=SUCCESS){
cerr << "system error\n COND_WAIT flush2device - exiting!!!\n";
exit(1);
}
cout << "should be right after " << task_id << " signal" << endl;
if (pthread_mutex_unlock(&id2cvLock) != SUCCESS) {
cerr << "system error\n UNLOCKING MUTEX flush2device -exiting!!!\n";
exit(1);
}
Run Code Online (Sandbox Code Playgroud)
}
在另一个代码部分,还有的唤醒部分(信令):
//id2cv is a map <int, pthread_cond_t*> variable. - the value is a pointer to the cv on
//which we call with the broadcast method.
if(pthread_mutex_lock(&id2cvLock)!=SUCCESS){
cerr <<"system error\n";
exit(1);
}
id2cv.erase(nextBuf->_taskID);
cout << "In Thread b4 signal, i'm tID " <<nextBuf->_taskID << endl;
if (pthread_cond_broadcast(nextBuf->cv) != 0) {
cerr << "system error SIGNAL_CV doThreads\n";
exit(1);
}
cout << "In doThread, after erasing id2cv " << endl;
if(pthread_mutex_unlock(&id2cvLock)!=SUCCESS){
cerr <<"system error\n;
exit(1);
}
Run Code Online (Sandbox Code Playgroud)
大多数运行工作都很好,但偶尔程序只是停止"反应" - 第一种方法(上面)只是没有通过cond_wait部分 - 似乎没有人真正按时向她发送信号(或从其他一些原因) - 而另一种方法(代码的最后一部分是其中的一部分)继续运行.
我在互斥和信号的逻辑上哪里出错了?我已经检查过pthread_cond_t变量在调用cond_wait和cond_broadcast方法之前仍处于"活动状态",并且该区域中没有任何内容似乎是错误的.
尽管它的名字,pthread_cond_wait是一种未有条件等待的一个条件.pthread_cond_wait除非您已确认有待等待的内容,否则您不得致电,并且等待的内容必须受相关联的互斥锁保护.
条件变量是无状态的,应用程序负责存储等待事物的状态,称为"谓词".
规范模式是:
pthread_mutex_lock(&mutex);
while(!ready_for_me_to_do_something)
pthread_cond_wait(&condvar, &mutex);
do_stuff();
ready_for_me_to_do_something=false; // this may or may not be appropriate
pthread_mutex_unlock(&mutex);
Run Code Online (Sandbox Code Playgroud)
和:
pthread_mutex_lock(&mutex);
ready_for_me_to_do_something=true;
pthread_cond_broadcast(&condvar);
pthread_mutex_unlock(&mutex);
Run Code Online (Sandbox Code Playgroud)
注意这段代码如何维护ready_for_me_to_do_something变量中的状态,等待的线程在循环中等待,直到该变量为真.注意互斥锁如何保护共享变量,并保护条件变量(因为它也在线程之间共享).
这不是使用条件变量的唯一正确方法,但很容易在任何其他用途中遇到麻烦.pthread_cond_wait即使没有理由等待你也会打电话.如果你在使用它之前等待你的妹妹回家,并且她已经回来了,你将会等待很长时间.