Linux-条件变量

来源:互联网 发布:淘宝好评卡片 编辑:程序博客网 时间:2024/06/03 18:35

1.条件变量
条件变量描述临界资源内的状态。
条件变量是线程中的东西,就是等待某一条件的发生,和信号一样。
条件变量使我们可以睡眠等待某种条件出现。
条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待”条件变量的条件成立”而挂起;另一个线程使”条件成立”(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起
返回值:成功返回0,失败返回错误号。
和Mutex的初始化和销毁类似,pthread_cond_init函数初始化⼀个Condition Variable,attr参数 为NULL则表⽰缺省属性,pthread_cond_destroy函数销毁⼀个Condition Variable。如果ConditionVariable是静态分配的,也可以⽤宏定义PTHEAD_COND_INITIALIZER初始化,相当于 ⽤pthread_cond_init函数初始化并且attr参数为NULL。 Condition Variable的操作可以⽤下列函数:
可见,⼀个Condition Variable总是和⼀个Mutex搭配使⽤的。 ⼀个线程可以调⽤pthread_cond_wait在⼀个Condition Variable上阻塞等待,这个函数做以下三步操作:
1. 释放Mutex
2. 阻塞等待
3. 当被唤醒时,重新获得Mutex并返回
pthread_cond_timedwait函数还有⼀个额外的参数可以设定等待超时,如果到达了abstime所指定的 时刻仍然没有别的线程来唤醒当前线程,就返回ETIMEDOUT。⼀个线程可以调⽤pthread_cond_signal唤醒在某个Condition Variable上等待的另⼀个线程,也可以调⽤pthread_cond_broadcast唤醒在这个Condition Variable上等待的所有线程。
2.生产者和消费者模型
3种关系:生产者-生产者:互斥关系;消费者-消费者:互斥;生产者-消费者:互斥和同步
2种角色:生产者,消费者;
1个交易场所
为了方便记忆,简称321原则
3.代码实现:
//采用链表实现

#include<stdio.h>#include<pthread.h>#include<stdlib.h>typedef struct _node{    int data;    struct _node *next;}node_t,*node_p,**node_pp;node_p head=NULL;pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;pthread_cond_t cond=PTHREAD_COND_INITIALIZER;static node_p alloc_node(int _d){    node_p tmp=(node_p)malloc(sizeof(node_t));    if(!tmp){        perror("malloc");        exit(1);    }    tmp->data=_d;    tmp->next=NULL;     }static void delete_node(node_p _n){    if(_n)    {        free(_n);}}static int isEmpty(node_p _h){    return _h->next==NULL? 1:0; }void initList(node_pp _h){    *_h=alloc_node(0);}void pushFront(node_p _h,int _d){    node_p tmp=alloc_node(_d);    tmp->next=_h->next;    _h->next=tmp;}void popFront(node_p _h,int *_out){    if(!isEmpty(_h)){        node_p p=_h->next;        _h->next=p->next;        *_out=p->data;        delete_node(p);    }}void destroyList(node_p _h){    int out=0;    while(!isEmpty(_h)){        popFront(_h,&out);        }        delete_node(_h);}void showList(node_p _h){    node_p start=_h->next;    while(start)    {        printf("%d",start->data);        start=start->next;    }}//void *product(void *arg)//{//    while(1){//      int p=rand()%1234;//      pthread_mutex_lock(&lock);//      pushFront(head,p);//      pthread_mutex_unlock(&lock);//      printf("product done: %d\n",p);//      sleep(1);//      }//}//void *consume(void* arg)//{//    int c;//    while(1){//        c=-1;//        pthread_mutex_lock(&lock);//        if(!isEmpty(head)){//        popFront(head,&c);//        }//        pthread_mutex_unlock(&lock);//        printf("consumer done: %d\n",c);//    }//}void *product(void *arg){    while(1){        int p=rand()%1234;        pthread_mutex_lock(&lock);        pushFront(head,p);        pthread_mutex_unlock(&lock);        pthread_cond_signal(&cond);        printf("product done: %d\n",p);        sleep(1);        }}void *consume(void* arg){    int c;    while(1){        c=-1;        pthread_mutex_lock(&lock);        while(!isEmpty(head)){            printf("consumer begin waiting...\n");            pthread_cond_wait(&cond,&lock);        }        popFront(head,&c);        pthread_mutex_unlock(&lock);        printf("consumer done: %d\n",c);    }}int main(){    initList(&head);    pthread_t p,c;    pthread_create(&p,NULL,product,NULL);    pthread_create(&c,NULL,consume,NULL);    pthread_join(p,NULL);    pthread_join(c,NULL);    pthread_mutex_destroy(&lock);    pthread_cond_destroy(&cond);    destroyList(head);   // int i=0;    //for(;i<10;i++)   // {       // pushFront(head,i);        //showList(head);        //printf("\n");        //sleep(1);        //}       //int out=0;        //for(;i>5;i--){          // popFront(head,&out);           //printf("\n");           //showList(head);           //sleep(1);            //}    // destroyList(head);    return 0; }

这里写图片描述

这里写图片描述
如果没有用Makefile编译代码,而采用gcc编译,可能会出现下面错误
/tmp/ccf92ZX8.o: In function main':
mycp.c:(.text+0x292): undefined reference to
pthread_create’
mycp.c:(.text+0x2b6): undefined reference to pthread_create'
mycp.c:(.text+0x2ca): undefined reference to
pthread_join’
mycp.c:(.text+0x2de): undefined reference to `pthread_join’
collect2: ld returned 1 exit status
原因是pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a。
所以在使用pthread_create()创建线程,以及调用 pthread_atfork()函数建立fork处理程序时,需要链接该库。
问题解决如下:
在编译中要加 -lpthread参数,gcc mycp.c -lpthread

原创粉丝点击