免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: iw1210
打印 上一主题 下一主题

[C] 像这样假设pthread_cond_wait函数没有第二个参数,不也能实现同样的功能么。 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2013-01-17 18:13 |只看该作者
windoze 发表于 2013-01-17 18:09
回复 19# iw1210

Unix的一个设计原则就是,每个功能都要在保持完整的前提下尽量的小,也就是常说的高内聚低耦合。
以上面的mutex和cv为例,cv用来保存和检查状态,mutex用来做同步和并发控制,这两组功能是独立的,各自可用。


PS. 好吧,POSIX中cv不能离开mutex使用,但是理论上说其实也不是非这样不可,没有mutex的cv无非就是会有一些race condition罢了。



再致敬!!

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
22 [报告]
发表于 2013-01-17 18:20 |只看该作者
本帖最后由 windoze 于 2013-01-17 18:25 编辑

回复 21# iw1210

另外,考虑到cv的典型使用方式:

  1. pthread_mutex_lock(mtx)
  2. while( cond_is_not_satisfied(...) ) {
  3. pthread_cond_wait(cv, mtx);
  4. }
  5. actions_on_condition(...);
  6. pthread_mutex_unlock(mtx);
复制代码
如果把mutex放在cv里面,API就没法保证cond_is_not_satisfied和actions_on_condition()在mutex被lock的状态下安全执行。
如果要保证这一点,API就得设计成这样:

  1. pthread_cond_wait(cv, cond_check_callback, actions_on_condition_callback)
复制代码
其中cond_check_callback是用来检查条件的回调函数指针,actions_on_condition_callback是条件满足时要执行的函数指针。

API没有更简单,反而更复杂了。

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
23 [报告]
发表于 2013-01-17 18:24 |只看该作者
windoze 发表于 2013-01-17 18:09
回复 19# iw1210

Unix的一个设计原则就是,每个功能都要在保持完整的前提下尽量的小,也就是常说的高内聚低耦合。
以上面的mutex和cv为例,cv用来保存和检查状态,mutex用来做同步和并发控制,这两组功能是独立的,各自可用。

PS. 好吧,POSIX中cv不能离开mutex使用,但是理论上说其实也不是非这样不可,没有mutex的cv无非就是会有一些race condition罢了。


正交分解就基本摸到问题核心了。

想象一下实际问题。比如一个有GUI界面、有read_buf和write_buf的多线程程序,这程序你怎么写?


方案A:
定义GUI_mutex/read_buf_mutex/write_buf_mutex,分别保护这三个公共资源;需要访问涉及哪个资源的东西,就用哪个资源的mutex。

这个方案显然清晰明了,解决问题毫无压力。


方案B:
让cv(以及GUI上的每个元素、read/wrete_buf相关的cv等等)都自带mutex。

好吧,如果我需要先完成buf的更新、后改变cv,以允许其它等待者去读buf(否则就会出现脏读),用方案B该怎么做?一个一个锁它们自带的mutex吗?如果你锁了cv_read_buf_A、另一个线程锁了cv_read_buf_B呢?

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
24 [报告]
发表于 2013-01-17 18:27 |只看该作者
回复 22# windoze


    你这个例子比我的更清晰明了。

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
25 [报告]
发表于 2013-01-17 18:28 |只看该作者
回复 23# shan_ghost


你说的这种情况其实需要3个cv,因为如果多个线程同时将同一个cv关联到不同的mutex是POSIX标准不允许的。
当然,这3个cv可以关联到同一个mutex,这就是目前POSIX API的灵活性所在。

论坛徽章:
0
26 [报告]
发表于 2013-01-17 18:38 |只看该作者
回复 23# shan_ghost

这种情况用三个 cv 不可以解决问题吗?

   

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
27 [报告]
发表于 2013-01-17 18:42 来自手机 |只看该作者
是啊,这就是我的意思。
cv用来保存状态,mutex用来同步

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
28 [报告]
发表于 2013-01-17 18:42 |只看该作者
iw1210 发表于 2013-01-17 18:38
回复 23# shan_ghost

这种情况用三个 cv 不可以解决问题吗?


我的意思本来就是用三个cv(甚至更多cv),注意我用了cv_read_buf_A和cv_read_buf_B——也就是在同一个资源上,也可能存在多个cv。但问题并不在这里。


因为mutex太分散(因为每个cv都带了自己的一份),所以当要修改其中一个资源时,就必须锁定与该资源相关的所有mutex,否则难以保证该资源的状态正常。而这个“锁定全部”的操作是非常容易出错的。

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
29 [报告]
发表于 2013-01-17 18:45 来自手机 |只看该作者
嗯,完全同意。
多个同步对象会导致同步的麻烦。
windows就是犯了这个错误,所以才需要WaitForMultipleObjects这个难看又难用的API

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
30 [报告]
发表于 2013-01-17 18:50 |只看该作者
本帖最后由 shan_ghost 于 2013-01-17 18:51 编辑
windoze 发表于 2013-01-17 18:45
嗯,完全同意。
多个同步对象会导致同步的麻烦。
windows就是犯了这个错误,所以才需要WaitForMultipleOb ...


是的。

记得我以前曾说过,能“封装”的前提,是必须先完成正交分解,使得系统的各部分之间完全透明。

让cv自带mutex,初看很简单,很自动化,“封装”的很好;但实际上它违反了模块/接口正交化这个设计原则,导致一旦真拿来用,就是复杂度爆炸。

这可能是初学者最容易犯的错误了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP