日期:2014-05-16  浏览次数:20716 次

关于条件变量的问题,求解答

#define PTHREAD_NUM 10

pthread_mutex_t lock;
pthread_cond_t cond;

void pthread_function(void *data)
{    
    pthread_detach(pthread_self());
    pthread_mutex_lock(&lock);
    if((int )data != PTHREAD_NUM - 1){
        pthread_cond_wait(&cond,&lock);
    }
//    sleep(1);
    printf("this thread id is %u!\n",pthread_self());
    pthread_cond_signal(&cond);
//    pthread_cond_broadcast(&cond);
    pthread_mutex_unlock(&lock);
}

int main()
{
    pthread_mutex_init(&lock,0);
    pthread_cond_init(&cond,0);

    int i = 0;
    pthread_t thread[PTHREAD_NUM] = {0};
    
    for(i = 0;i < PTHREAD_NUM;i++){
        pthread_create(&thread[i],0,pthread_function,(void *)i);
        printf("%d---%lu\n",i,thread[i]);
    }
    printf("\n");
    sleep(20);
 
    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&lock);
    return 0;
}


我用循环开了10个线程 将前九个用互斥锁锁住,并放到条件变量中
然后在第十个的时候 用 pthread_cond_signal 释放一个
释放的那个线程在打印一条信息后 再次用pthread_cond_signal释放一个
但是 打印出来的信息 只有5-8条(不固定) 为什么那几天没有打印出来呢?
PS:用pthread_cond_broadcast的时候 十条都能打印出来
UC

------解决方案--------------------
给你说说为什么错吧, 看样你没理解.

假设就2个线程, 那么线程1掠过if直接signal(但没人wait), 接下来线程0尚未执行到lock, 检查if成立后wait, 于是死锁了.

为什么会很难发现这个错误, 因为平时都是正常的业务逻辑需求, 从来不会让条件变量做错误的事情.

这里楼主就是让条件变量做了与条件无关的事, 即你signal是因为你认为条件已经成立了, 而对于线程0来说条件是永不成立的(根本不算条件, 所以逻辑是有漏洞的), cond_wait的原子性在这里毫无意义.