pThread线程(三) 线程同步--条件变量

时间:2014-12-26 14:31:55   收藏:0   阅读:533

条件变量(Condition Variables)

参考资料:http://game-lab.org/posts/posix-thread-cn/#5.1

条件变量是什么?

主线程
  • 声明并初始化需要同步的全局数据或变量(例如”count“)
  • 声明并初始化一个条件变量对象
  • 声明并初始化一个与条件变量关联的互斥量
  • 创建线程A和B并开始运行
线程A
  • 线程运转至某一个条件被触发(例如,”count“必须达到某个值)
  • 锁定相关联的互斥量并检查全局变量的值
  • 调用pthread_con_wait()阻塞线程等待线程B的信号。请注意,调用pthread_con_wait()以自动的原子方式(atomically)解锁相关联的互斥量,以便于可以被线程B使用。
  • 当收到信号时,唤醒线程。互斥量被以自动的原子方式被锁定。
  • 明确的解锁互斥量。
  • 继续
Thread B
  • 线程运转
  • 锁定相关联的互斥量
  • 更改线程A正在等待的全局变量的值
  • 检查线程A等待的变量值,如果满足条件,发信号给线程A
  • 解锁互斥量
  • 继续
主线程
    Join / Continue

 

 

创建和销毁条件变量

函数:

pthread_cond_init (condition,attr)
pthread_cond_destroy (condition)

pthread_condattr_init (attr)
pthread_condattr_destroy (attr)

用法:

  1. 静态初始化,像这样声明:pthread_con_t myconvar = PTHREAD_CON_INITIALIZER;
  2. 动态初始化,使用pthread_cond_init()函数。用创建条件变量的ID作为件参数传给线程,这种方法允许设置条件变量对象属性attr。

        注意,不是所有的实现都用得着process-shared属性。

 

条件变量的等待和信号发送

函数:

pthread_cond_wait (condition,mutex)
pthread_cond_signal (condition)
pthread_cond_broadcast (condition)

使用:

  1. 在调用pthread_cond_wait()之前锁定互斥量失败,可致使其无法阻塞;
  2. 在调用pthread_cond_signal()之后解锁互斥量失败,则致使与之对应的pthread_cond_wait()函数无法完成,并仍保持阻塞状态。

 实例分析

 1 /******************************************************************************
 2  * 描述:
 3  *     应用Pthreads条件变量的实例代码,主线程创建三个线程,其中两个为“count”变量做
 4  * 加法运算,第三个线程监视“count”的值。当“count”达到一个限定值,等待线程准备接收来
 5  * 自于两个加法线程中一个的信号,等待 线程唤醒后更改“count”的值。程序继续运行直到加法
 6  * 线程达到TCOUNT的值。最后,主程序打印出count的值。
 7  ******************************************************************************/
 8 #include <pthread.h>
 9 #include <stdio.h>
10 #include <stdlib.h>
11 
12 #define NUM_THREADS  3
13 #define TCOUNT 5       //单线程轮询次数
14 #define COUNT_LIMIT 7  //发送信号的次数
15 int count = 0; //全局的累加量
16 
17 pthread_mutex_t count_mutex;
18 pthread_cond_t count_threshold_cv;
19 
20 void *inc_count(void *t) {
21     int i;
22     long my_id = (long) t;
23 
24     for (i = 0; i < TCOUNT; i++) {
25         pthread_mutex_lock(&count_mutex);
26         count++;
27         /*
28          * 检查count的值,如果条件满足就发信号给等待线程
29          * 注意,此处是用信号量锁定的。
30          * */
31         if (count < COUNT_LIMIT) {
32             printf("inc_count(): thread %ld, count = %d  Threshold reached. ",
33                     my_id, count);
34             pthread_cond_signal(&count_threshold_cv);
35             printf("Just sent signal.\n");
36         }
37         printf("inc_count(): thread %ld, count = %d, unlocking mutex\n", my_id,
38                 count);
39         pthread_mutex_unlock(&count_mutex);
40 
41         /*为线程轮询互斥锁增加延时*/
42         sleep(1);
43     }
44     pthread_exit(NULL);
45 }
46 
47 void *watch_count(void *t) {
48     long my_id = (long) t;
49     printf("Starting watch_count(): thread %ld\n", my_id);
50 
51     /*锁定互斥量并等待信号,注意,pthread_cond_wait函数在等待时将自动以自动原子方式
52      * 解锁互斥量。还有,请注意,如果等待线程运行到等待函数之前已经满足COUNT_LIMIT的
53      * 条件判断,轮询会忽略掉等待函数,
54      * */
55     while (count < COUNT_LIMIT) {
56         pthread_mutex_lock(&count_mutex);
57         printf("watch_count(): thread %ld going into wait...\n", my_id);
58         pthread_cond_wait(&count_threshold_cv, &count_mutex);
59         printf("watch_count(): thread %ld Condition signal received.\n", my_id);
60 
61         printf("watch_count(): thread %ld count now = %d.\n", my_id, count);
62         pthread_mutex_unlock(&count_mutex);
63     }
64     pthread_exit(NULL);
65 }
66 
67 int main(int argc, char *argv[]) {
68     int i;
69     long t1 = 1, t2 = 2, t3 = 3;
70     pthread_t threads[3];
71     pthread_attr_t attr;
72 
73     /*初始化互斥量和条件变量对象*/
74     pthread_mutex_init(&count_mutex, NULL);
75     pthread_cond_init(&count_threshold_cv, NULL);
76 
77     /*创建线程时设为可连接状态,便于移植*/
78     pthread_attr_init(&attr);
79     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
80     pthread_create(&threads[0], &attr, watch_count, (void *) t1);
81     pthread_create(&threads[1], &attr, inc_count, (void *) t2);
82     pthread_create(&threads[2], &attr, inc_count, (void *) t3);
83 
84     /* 等待所有线程完成*/
85     for (i = 1; i < NUM_THREADS; i++) {
86         pthread_join(threads[i], NULL);
87     }
88    /*发送信号给监听线程*/
89     pthread_cond_signal(&count_threshold_cv); 
90     pthread_join(threads[0],NULL);
91     printf("Main(): Waited on %d threads. Final value of count = %d. Done.\n",
92             NUM_THREADS, count);
93 
94     /*清除并退出 */
95     pthread_attr_destroy(&attr);
96     pthread_mutex_destroy(&count_mutex);
97     pthread_cond_destroy(&count_threshold_cv);
98     pthread_exit(NULL);
99 }

 

 

原文:http://www.cnblogs.com/dongsheng/p/4186560.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!