pthread条件变量condition(配合mutex锁使用)

pthread条件变量condition(配合mutex锁使用)_第1张图片

为了便于理解,画了个图,一系列动作完成下来只需要一个mutex和一个conditional_variable。
wait函数包含了很多操作,在wait之前和之后必须要手动加锁/解锁mutex,保证同一时间只有一个人对条件变量cond进行使用。
先unlock或者先发送signal()都可以,Linux推荐吧signal()包在中间。
注意,即便以及发送了signal,却没有unlock,那么及时wait收到了信号,也无法返回,因为wait最后还需要锁住mutex,没抢到的话,只能在那继续阻塞。
 
pthread conditional_variable:
    cond_wait: (usage:)  lock -> cond_wait -> unlock
               (在调用wait时阻塞住线程,等待cond_signal的通知)
             What's inside the function wait()? It unlocks the mutex and then blocks the thread.
             The purpose of lock is to prevent simultaneous requests of wait().
             If cond_signal happens, it will stop blocking and lock the mutex automatically.
    cond_signal:  (usage:)  lock -> cond_signal -> unlock 
 
    here, lock and unlock means you have to write them explicitly in code by using pthread_mutex_lock


下面列出一个Demo:

#include <stdio.h>
C代码 : 
#include <stdlib.h>  
#include <pthread.h>  
struct msg{  
    struct msg *next;  
    int num;  
};  
  
struct msg *head;  
pthread_cond_t has_product;//Condition Variable  
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;//互斥锁初始化  
  
void *consumer(void *p)  
{  
    struct msg *mp;  
    for(;;){  
        pthread_mutex_lock(&lock);//保证生产与消费的互斥,消费者取得lock  
        while(head == NULL)  
            pthread_cond_wait(&has_product,&lock);  
 /*其实while这一过程并不是必需的,  pthread_cond_wait这一过程已经可以实现等待-执行可程了.但由于线程被唤醒的情况有多种,我们需要的是head!=NULL这种情况才会继续执行.而且pthread_cond_wait()这个方法还会有一个内在的执行过程,在pthread_cond_wait()这一过程中我们必需保证lock的持有,当线程刷新了等待队列之后,在被持起之前lock会被释放.
当另一个线程调用pthread_cond_signal()唤醒之前需要先把lock给释放了,因为调用pthread_cond_signal()后,消费进程需要重新通过pthread_cond_wait()这个方法获得lock,然后执行逻辑处理代码,最后消费进程释放lock.*/
 
        mp = head;  
        head = mp->next;  
        pthread_mutex_unlock(&lock);//释放lock  
        printf("Consumer %d\n",mp->num);  
        free(mp);  
        sleep(rand()%5);  
    }  
}  
  
void *producer(void *p)  
{  
    struct msg *mp;  
    for(;;){  
        mp = malloc(sizeof(struct msg));  
        mp->num = rand() % 1000+1;  
        printf("Produce %d\n",mp->num);  
        pthread_mutex_lock(&lock);//为保证操作的原子性获得lock  
        mp->next = head;  
        head = mp;  
        pthread_mutex_unlock(&lock);//释放lock  
        pthread_cond_signal(&has_product);//唤醒消费进程  
        sleep(rand()%5);  
  
    }  
}  
  
int main(int argc,char *argv[])  
{  
    pthread_t pid,cid;  
    srand(time(NULL));  
    cid = pthread_create(&cid,NULL,consumer,NULL);  
    pid = pthread_create(&pid,NULL,producer,NULL);  
    sleep(5);  
    pthread_join(pid,NULL);  
    pthread_join(cid,NULL);  
    return 0;  
}  


你可能感兴趣的:(linux)