广东梅州兴宁做网站公司,佛山网站建设网站建设,点餐小程序开发需要多少钱,中国小康建设网官方网站一.条件变量 条件变量是用来等待线程而不是上锁的#xff0c;条件变量通常和互斥锁一起使用。条件变量之所以要和互斥锁一起使用#xff0c;主要是因为互斥锁的一个明显的特点就是它只有两种状态#xff1a;锁定和非锁定#xff0c;而条件变量可以通过允许线程阻塞和等待另…   一.条件变量 条件变量是用来等待线程而不是上锁的条件变量通常和互斥锁一起使用。条件变量之所以要和互斥锁一起使用主要是因为互斥锁的一个明显的特点就是它只有两种状态锁定和非锁定而条件变量可以通过允许线程阻塞和等待另一个线程发送信号来弥补互斥锁的不足所以互斥锁和条件变量通常一起使用。 当条件满足的时候线程通常解锁并等待该条件发生变化一旦另一个线程修改了环境变量就会通知相应的环境变量唤醒一个或者多个被这个条件变量阻塞的线程。这些被唤醒的线程将重新上锁并测试条件是否满足。一般来说条件变量被用于线程间的同步当条件不满足的时候允许其中的一个执行流挂起和等待。 条件变量中常用的API 1).条件变量类型为:pthread_cond_t 类似互斥变量条件变量的初始化有两种方式: 静态pthread_cond_t myconPTHREAD_COND_INITIALIZER; 动态通过调用pthread_cond_init函数函数原型为 [cpp] view plain copy      静态pthread_cond_t myconPTHREAD_COND_INITIALIZER;   cond环境变量. attr条件变量属性. 成功返回0失败返回错误码. 2).条件变量摧毁函数pthread_cond_destroy(mycond); [cpp] view plain copy      int pthread_cond_destroy(pthread_cond_t *cond);   成功返回0失败返回错误码. 摧毁所指定的条件变量同时将会释放所给它分配的资源。调用该函数的进程也并不等待在参数所指定的条件变量上。 3).条件变量等待函数。pthread_cond_wait(mycond,mylock); [cpp] view plain copy      int pthread_cond_timedwait(pthread_cond_t *restrict cond,              pthread_mutex_t *restrict mutex,              const struct timespec *restrict abstime);       int pthread_cond_wait(pthread_cond_t *restrict cond,              pthread_mutex_t *restrict mutex);   cond条件变量 mutex互斥锁 pthread_cond_wait和pthread_cond_timedwait的区别 pthread_cond_timedwait函数类型与函数pthread_cond_wait,区别在于如果达到或是超过所引用的参数*abstime,它将结束并返回错误ETIME. timespec [cpp] view plain copy      typedef struct timespec      {         time_t     tv_sec;    //! 秒         long     tv_nsex;    //! 毫秒      }timespec_t;   当时间超过之前预设定的时会返回错误. 4).条件变量通知函数pthread_cond_signal和pthread_cond_broadcast [cpp] view plain copy      int pthread_cond_broadcast(pthread_cond_t *cond);   int pthread_cond_signal(pthread_cond_t *cond);   pthread_cond_signal和pthread_cond_broadcast的区别 pthread_cond_signal只唤醒一个在相同条件变量中阻塞的线程将会被唤醒 pthread_cond_broadcast唤醒等待队列中的所有线程 二.一个关于互斥锁和条件变量的栗子 栗子用互斥锁和条件变量的概念实现一个简单的生产者和消费者的模型。 生产者和消费者模型 1).满足互斥与同步条件用互斥锁和条件变量实现 2).多个生产者和消费者生产者和生产者属于互斥关系生产者和消费者属于互斥和同步关系消费者和消费者属于竞争关系需要互斥锁 3).生产者和消费者模型中存在如下几种关系和角色3种关系2种角色1种交换媒介(一般是一段内存) 下例以单生产者和单消费者交换媒介为链表实现的生产者消费者模型 [cpp] view plain copy      procon.c      #includestdio.h   #includestdlib.h   #includeassert.h   #includepthread.h      typedef struct LinkNode   {       int data;       struct LinkNode *next;   }Node;      pthread_mutex_t mylockPTHREAD_MUTEX_INITIALIZER;   pthread_cond_t mycondPTHREAD_COND_INITIALIZER;      Node *CreatNode(int data)   {       Node *NewNode(Node *)malloc(sizeof(Node));       if(NULL  NewNode)       {           perror(malloc);           return NULL;       }       NewNode-datadata;       NewNode-nextNULL;       return NewNode;   }      void InitLink(Node **head)   {       *headCreatNode(0);   }      int IsEmpty(Node *head)   {       assert(head);       if(head-next)           return 0;    //not empty       else           return 1;    //empty   }      void PushFront(Node *head,int data)   {       assert(head);       Node *NewNodeCreatNode(data);       NewNode-nexthead-next;       head-nextNewNode;   }      void PopFront(Node *head,int *data)   {       assert(data);       assert(head);       if(IsEmpty(head))       {           printf(empty link\n);           return ;       }       Node *delhead-next;       *datadel-data;       head-nextdel-next;       free(del);       delNULL;   }      void DisplayLink(Node *head)   {       assert(head);       Node *curhead-next;       while(cur)       {           printf(%d ,cur-data);           curcur-next;       }       printf(\n);   }      void DestroyLink(Node *head)   {       int data0;       assert(head);       while(!IsEmpty(head))       {           PopFront(head,data);       }       free(head);   }      void *product_run(void *arg)   {       int data0;       Node *head(Node *)arg;       while(1)       {           usleep(100000);           datarand()%1000;           pthread_mutex_lock(mylock);           PushFront(head,data);           pthread_mutex_unlock(mylock);           pthread_cond_signal(mycond);           printf(product is done,data%d\n,data);       }   }      void *consumer_run(void *arg)   {       int data0;       Node *head(Node *)arg;       while(1)       {           pthread_mutex_lock(mylock);           while(IsEmpty(head))           {               pthread_cond_wait(mycond,mylock);           }           PopFront(head,data);           pthread_mutex_unlock(mylock);           printf(consumer is done,data%d\n,data);       }   }      void testprocon()   {       Node *headNULL;       InitLink(head);       pthread_t tid1;       pthread_t tid2;       pthread_create(tid1,NULL,product_run,(void *)head);       pthread_create(tid2,NULL,consumer_run,(void *)head);          pthread_join(tid1,NULL);       pthread_join(tid2,NULL);       DestroyLink(head);       pthread_mutex_destroy(mylock);       pthread_cond_destroy(mycond);      }   int main()   {       testprocon();       return 0;   }      Makefile   procon:procon.c       gcc -o $ $^ -lpthread   .PHONY:clean   clean:       rm -f procon   总结 条件变量用在某个线程需要在某种条件才去保护它将要操作的临界区的情况下从而避免了线程不断轮询检查该条件是否成立而降低效率的情况这是实现了效率提高。 希望对读者有帮助吧~~~~