pthread_cond_wait没有从pthread_cond_broadcast中醒来

Zac*_*ach 2 c++ pthreads

在我的程序中,有一部分代码等待从代码的其他部分唤醒:
这是睡眠的部分:

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方法之前仍处于"活动状态",并且该区域中没有任何内容似乎是错误的.

Dav*_*rtz 5

尽管它的名字,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即使没有理由等待你也会打电话.如果你在使用它之前等待你的妹妹回家,并且她已经回来了,你将会等待很长时间.