线程条件变量pthread_cond_t和线程条件锁详解
来源:互联网 发布:科迅cms 编辑:程序博客网 时间:2024/05/16 01:45
线程条件变量pthread_cond_t和线程条件锁详解
参考文章
条件变量常与互斥锁同时使用,达到线程同步的目的:条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足。
APUE上,关于条件锁。其中有2条总结:
1.使用条件锁前必须先锁住对应的互斥锁。
2.条件锁进入阻塞(pthread_cond_wait)时自动解开对应互斥锁,而一旦跳出阻塞立即再次取得互斥锁,而这两个操作都是原子操作。
示例代码如下:
//互斥锁pthread_mutex_t counter_lock;//条件变量 pthread_cond_t counter_nonzero;int counter = 0;void decrement_counter(void *argv){ pthread_mutex_lock(&counter_lock); printf("thd1 decrement get the lock \n"); while(counter == 0) { printf("thd1 decrement before cond_wait\n"); pthread_cond_wait(&counter_nonzero, &counter_lock); /* 运行到此处条件锁会自动以原子操作的方式将互斥锁解锁 条件锁在收到pthread_cond_signal发出的信号后会尝试再次获取到互斥锁由于互斥锁已经被increment_counter函数持有 因此decrement_counter函数所在的线程进入休眠状态等待increment_counter函数所在的线程解锁互斥锁 当increment_counter函数所在的线程解锁互斥锁后decrement_counter函数所在的线程从休眠状态恢复开始运行 */ printf("thd1 decrement after cond_wait \n"); } counter--; printf("thd1 decrement:counter = %d \n", counter); pthread_mutex_unlock(&counter_lock);}void increment_counter(void *argv){ pthread_mutex_lock(&counter_lock); printf("thd2 increment get the lock\n"); if(counter == 0) { printf("thd2 increment before cond_signal\n"); pthread_cond_signal(&counter_nonzero);//发出条件变量信号 printf("thd2 increment after cond_signal\n"); } counter++; printf("thd2 increment:counter = %d \n", counter); pthread_mutex_unlock(&counter_lock);}void test_pthread_cond(){ printf("counter: %d\n", counter); pthread_t thd1, thd2; pthread_mutex_init(&counter_lock, NULL); pthread_cond_init(&counter_nonzero, NULL); int ret; printf("main1: before creating thd1 decrement \n"); ret = pthread_create(&thd1, NULL, (void *)decrement_counter, NULL);//先创建的是等待线程,用pthread_cond_wait if(ret){ perror("del:/n"); return ; } printf("main2:thd1 is created, begin create thd2 increment \n"); ret = pthread_create(&thd2, NULL, (void *)increment_counter, NULL);//后创建的是激活线程,用pthread_cond_signal if(ret){ perror("inc: /n"); return ; } printf("main3:after thd1 and thd2, begin sleep and exit!\n"); sleep(3); return ;}/*运行结果:counter: 0main1: before creating thd1 decrement main2:thd1 is created, begin create thd2 increment main3:after thd1 and thd2, begin sleep and exit!thd1 decrement get the lock thd1 decrement before cond_waitthd2 increment get the lockthd2 increment before cond_signalthd2 increment after cond_signalthd2 increment:counter = 1 thd1 decrement after cond_wait thd1 decrement:counter = 0*/
//互斥锁pthread_mutex_t mutex;//条件变量pthread_cond_t cond_l;int i = 1;void* run(void *s){ pthread_mutex_lock(&mutex); while(i == 1) { printf("线程%u进入等待状态\n", (unsigned int)pthread_self()); pthread_cond_wait(&cond_l, &mutex); } printf("已经解开%u\n", (unsigned int)pthread_self()); pthread_mutex_unlock(&mutex); i = 1; return ((void *) 1);}void testRun(){ pthread_t pid1; pthread_t pid2; pthread_t pid3; pthread_t pid4; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond_l, NULL); pthread_create(&pid1, NULL, run, NULL ); printf("new thread:%u\n", (unsigned int)pid1); sleep(1); pthread_create(&pid2, NULL, run, NULL ); printf("new thread:%u\n", (unsigned int)pid2); sleep(1); pthread_create(&pid3, NULL, run, NULL ); printf("new thread:%u\n", (unsigned int)pid3); sleep(1); pthread_create(&pid4, NULL, run, NULL ); printf("new thread:%u\n", (unsigned int)pid4); sleep(1);#if 0 //不注释 pthread_mutex_lock(&mutex); /* new thread:3289088 线程3289088进入等待状态 new thread:3825664 线程3825664进入等待状态 new thread:4362240 线程4362240进入等待状态 new thread:4898816 线程4898816进入等待状态 release signal release signal */#endif#if 1 //注释掉 //pthread_mutex_lock(&mutex); /* new thread:3289088 线程3289088进入等待状态 new thread:3825664 线程3825664进入等待状态 new thread:4362240 线程4362240进入等待状态 new thread:4898816 线程4898816进入等待状态 release signal 已经解开3289088 release signal 已经解开3825664 */#endif //pthread_cond_signal每次只会唤醒一个条件锁,唤醒的顺序跟阻塞在条件锁的顺序相同 i = 2; pthread_cond_signal(&cond_l); printf("release signal\n"); sleep(1); i = 2; pthread_cond_signal(&cond_l); printf("release signal\n"); sleep(1); //pthread_join()的作用可以这样理解:主线程等待子线程的终止。 //也就是在子线程调用了pthread_join()方法后面的代码,只有等到子线程结束了才能执行。 pthread_join(pid1, NULL ); pthread_join(pid2, NULL ); pthread_join(pid3, NULL ); pthread_join(pid4, NULL );}
阅读全文
0 0
- 线程条件变量pthread_cond_t和线程条件锁详解
- 线程条件变量pthread_cond_t
- 线程条件变量pthread_cond_t
- 线程条件变量pthread_cond_t
- 线程条件变量pthread_cond_t
- 线程条件变量pthread_cond_t
- 线程条件变量pthread_cond_t
- 线程条件变量pthread_cond_t用法
- 线程同步: 条件变量pthread_cond_t
- Linux线程浅析[线程的同步和互斥之线程同步的条件变量pthread_cond_t]
- 线程条件变量详解
- C++11 线程、锁和条件变量
- 线程与条件变量和锁
- Linux多线程编程详解----条件变量pthread_cond_t
- Linux多线程编程详解----条件变量pthread_cond_t
- 条件变量 条件缩 pthread_cond_t
- 条件变量 pthread_cond_t
- pthread_cond_t条件变量
- JVM垃圾收集算法
- 防止过拟合的几种范数的介绍
- HEVC的并行解码语法和条带结构Slice和Tile
- 相对定位的元素会在原先的地方
- php采集模拟点击伪造IP,伪造浏览器useragent伪造来源防反爬虫例子--
- 线程条件变量pthread_cond_t和线程条件锁详解
- Mysql的列索引和多列索引(联合索引)(张高伟)
- iOS开发之应用内快速切换语言包(不跟随系统语言,不用重启)
- Qt5.8 异形窗口
- iOS 为什么必须在主线程中操作UI
- 图片懒加载
- android wifi相关知识
- WxMasonry微信小程序瀑布流布局模式
- Redis 主从复制高可用方案