linux条件变量
条件变量变量也是出自POSIX线程标准,另一种线程同步机制,。主要用来等待某个条件的发生。可以用来同步同一进程中的各个线程。当然如果一个条件变量存放在多个进程共享的某个内存区中,那么还可以通过条件变量来进行进程间的同步。
每个条件变量总是和一个互斥量相关联,条件本身是由互斥量保护的,线程在改变条件状态之间必须要锁住互斥量。条件变量相对于互斥量最大的优点在于允许线程以无竞争的方式等待条件的发生。当一个线程获得互斥锁后,发现自己需要等待某个条件变为真,如果是这样,该线程就可以等待在某个条件上,这样就不需要通过轮询的方式来判断添加,大大节省了CPU时间。
例子(一个生产者,一个消费者)
条件变量是一种类似操作系统里提到的生产者-消费者算法的同步机制,允许线程以无竞争的方式等待特定条件的发生。
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int beginnum = 1000;
typedef struct _ProdInfo{
int num;
struct _ProdInfo *next;
}ProdInfo;
ProdInfo *Head = NULL;
void *thr_producter(void *arg){
//负责在链表添加数据
while (1)
{
ProdInfo * prod = malloc(sizeof(ProdInfo));
prod->num = beginnum++;
printf("----%s----self=%lu----%d\n",__FUNCTION__,pthread_self(),prod->num);
pthread_mutex_lock(&mutex);
//add to list
prod->next = Head;
Head = prod;
pthread_mutex_unlock(&mutex);
//发起通知
pthread_cond_signal(&cond);
sleep(rand()%4);
}
return NULL;
}
void *thr_customer(void *arg){
ProdInfo * prod = NULL;
while (1)
{
//取链表的数据
pthread_mutex_lock(&mutex);
while(Head == NULL){
pthread_cond_wait(&cond,&mutex);//在此之前必须先加锁
}
prod = Head;
Head = Head->next;
printf("----%s----self=%lu----%d\n",__FUNCTION__,pthread_self(),prod->num);
pthread_mutex_unlock(&mutex);
sleep(rand()%4);
free(prod);
}
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_t tid[2];
pthread_create(&tid[0],NULL,thr_producter,NULL);
pthread_create(&tid[1],NULL,thr_customer,NULL);
pthread_join(tid[0],NULL);
pthread_join(tid[1],NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
输出
----thr_producter----self=140037231408896----1000
----thr_customer----self=140037223016192----1000
----thr_producter----self=140037231408896----1001
----thr_customer----self=140037223016192----1001
----thr_producter----self=140037231408896----1002
----thr_producter----self=140037231408896----1003
----thr_customer----self=140037223016192----1003
----thr_customer----self=140037223016192----1002
----thr_producter----self=140037231408896----1004
----thr_customer----self=140037223016192----1004
----thr_producter----self=140037231408896----1005
----thr_customer----self=140037223016192----1005
----thr_producter----self=140037231408896----1006
----thr_customer----self=140037223016192----1006
----thr_producter----self=140037231408896----1007
例子2(一个生产者,多个消费者)
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int beginnum = 1000;
typedef struct _ProdInfo{
int num;
struct _ProdInfo *next;
}ProdInfo;
ProdInfo *Head = NULL;
void *thr_producter(void *arg){
//负责在链表添加数据
while (1)
{
ProdInfo * prod = malloc(sizeof(ProdInfo));
prod->num = beginnum++;
printf("----%s----self=%lu----%d\n",__FUNCTION__,pthread_self(),prod->num);
pthread_mutex_lock(&mutex);
//add to list
prod->next = Head;
Head = prod;
pthread_mutex_unlock(&mutex);
//发起通知
pthread_cond_signal(&cond);
sleep(rand()%4);
}
return NULL;
}
void *thr_customer(void *arg){
ProdInfo * prod = NULL;
while (1)
{
//取链表的数据
pthread_mutex_lock(&mutex);
while(Head == NULL){
pthread_cond_wait(&cond,&mutex);//在此之前必须先加锁
}
prod = Head;
Head = Head->next;
printf("----%s----self=%lu----%d\n",__FUNCTION__,pthread_self(),prod->num);
pthread_mutex_unlock(&mutex);
sleep(rand()%4);
free(prod);
}
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_t tid[2];
pthread_create(&tid[0],NULL,thr_producter,NULL);
pthread_create(&tid[1],NULL,thr_customer,NULL);
pthread_create(&tid[2],NULL,thr_customer,NULL);
pthread_join(tid[0],NULL);
pthread_join(tid[1],NULL);
pthread_join(tid[2],NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}