一.条件变量
线程间的同步还有一种情况:线程A需要等某个条件成立才能继续往下执行,当条件不成立时,线程A就阻塞等待,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行。在pthread库中通过条件变量(Condition Variable)来阻塞等待一个条件,或者唤醒等待这个条件的线程,条件变量的初始化和销毁函数如下:
返回值:成功返回0,失败返回错误码。
和Mutex的初始化和销毁类似,如果Condition Variable是静态分配的,也可以用宏定义PTHREAD_COND_INITIALIAER初始化,相当于用pthread_cond_init初始化并且参数attr为NULL。 Condition Variable的操作可以用下列函数:
返回值:成功返回0,失败返回错误号
一个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上等待的所有线程。
二.演示生产者――消费者
生产者生产一个结构体串在链表的表头上,消费者从 表头取走结构体。
代码实现如下:
1 #include<stdio.h> 2 #include<stdlib.h>
3 #include<pthread.h>
4 typedef int data_type;
5 typedef int* data_type_p;
6 typedef struct _node{
7 struct _node* _next;
8 data_type _data;
9 }node_t,*node_p,**node_pp;
10 node_p head=NULL;
11 static pthread_mutex_t lock1=PTHREAD_MUTEX_INITIALIZER;
12 static pthread_mutex_t lock2=PTHREAD_MUTEX_INITIALIZER;
13 static pthread_mutex_t lock3=PTHREAD_MUTEX_INITIALIZER;
14 static pthread_cond_t need_product=PTHREAD_COND_INITIALIZER;
15 static node_p buy_node(data_type data)
16 {
17 node_p tmp=(node_t *)malloc(sizeof(node_t));
18 if(tmp)
19 {
20 tmp->_data=data;
21 tmp->_next=NULL;
22 return tmp;
23 }
24 return NULL;
25 }
26 void init_list(node_pp head)
27 {
28 *head=buy_node(0);
29 }
30 void push_back(node_p head,data_type data)
31 {
32 node_p tmp=buy_node(data);
33 if(head->_next==NULL)
34 {
35 head->_next=tmp;
36 tmp->_next=NULL;
37 }
38 else
39 {
40 node_p cur=head;
41 while(cur->_next)
42 {
43 cur=cur->_next;
44 }
45 cur->_next=tmp;
46 tmp->_next=NULL;
47 }
48 }
49 void push_front(node_p head,data_type data)
50 {
51 node_p tmp=buy_node(data);
52 tmp->_next=head->_next;
53 head->_next=tmp;
54 }
55 int pop_front(node_p head,data_type_p buf)
56 {
57 if(head->_next==NULL)
58 {
59 *buf = -1;
60 return -1;
61 }
62 else
63 {
64 node_p tmp=NULL;
65 tmp=head->_next;
66 *buf=tmp->_data;
67 head->_next=tmp->_next;
68 tmp->_next=NULL;
69 if(tmp)
70 {
71 free(tmp);
72 tmp=NULL;
73 }
74 return 0;
75 }
76 }
77 void show_list(node_p head)
78 {
79 node_p tmp=head->_next;
80 if(tmp)
81 {
82 printf("%d ",tmp->_data);
83 fflush(stdout);
84 tmp=tmp->_next;
85 }
86 printf("\n");
87 }
88 void *product(void *arg)
89 {
90 pthread_mutex_lock(&lock2);
91 int i=0;
92 while(1)
93 {
94 pthread_mutex_lock(&lock1);
95 printf("product success,produce num:%d,,,val is:%d\n",\
96 (int)arg,i);
97 push_back(head,i++); //FIFO
98 //push_front(head,i++); //LIFO
99 pthread_mutex_unlock(&lock1);
100 pthread_cond_signal(&need_product);
101 sleep(2);
102 }
103 pthread_mutex_unlock(&lock2);
104 }
105 void *consumer(void *arg)
106 {
107 pthread_mutex_unlock(&lock3);
108 data_type buf;
109 while(1)
110 {
111 pthread_mutex_lock(&lock1);
112 while(pop_front(head,&buf)==-1)
113 {
114 printf("wait**********\n");
115 pthread_cond_wait(&need_product,&lock1);
116 }
117 pthread_mutex_unlock(&lock1);
118 printf("consumer success,consumer num:%d,,,val is:%d\n",\
119 (int)arg,buf);
120 sleep(5);
121 }
122 pthread_mutex_unlock(&lock3);
123 }
124 int main()
125 {
126 init_list(&head);
127 pthread_t tid1,tid2,tid3,tid4;
128 pthread_create(&tid1,NULL,product,(void*)1);
129 pthread_create(&tid2,NULL,product,(void*)1);
130 pthread_create(&tid3,NULL,consumer,(void*)2);
131 pthread_create(&tid4,NULL,consumer,(void*)2);
132 pthread_join(tid1,NULL);
133 pthread_join(tid2,NULL);
134 pthread_join(tid3,NULL);
135 pthread_join(tid4,NULL);
136 return 0;
137 }
FIFO的运行结果:
LIFO的运行结果:
多生产者――多消费者的运行结果:
本文出自 “zwy” 博客,请务必保留此出处http://10548195.blog.51cto.com/10538195/1766414