免费注册 查看新帖 |

Chinaunix

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

请高手解释下程序运行过程:多线程加锁阻塞问题 [复制链接]

论坛徽章:
0
41 [报告]
发表于 2011-11-23 17:36 |只看该作者
回复 40# digdeep126

晕,,,,,哥们,你这是从哪里想来的,你看看标准吧

论坛徽章:
0
42 [报告]
发表于 2011-11-23 17:38 |只看该作者
本帖最后由 digdeep126 于 2011-11-23 18:00 编辑

回复 41# 埋头苦编
还是你自己想想清楚吧!兄弟。你想想文件锁是如何使用的。

论坛徽章:
0
43 [报告]
发表于 2011-11-23 18:02 |只看该作者
本帖最后由 digdeep126 于 2011-11-23 18:04 编辑
回复  digdeep126

晕,,,,,哥们,你这是从哪里想来的,你看看标准吧
埋头苦编 发表于 2011-11-23 17:36


你看的什么标准?对锁的处理,必须是所有的线程以一致的方式来处理:先“加锁”,获得锁之后进行一些处理,然后“释放锁”;然后其它的线程的”加锁“操作才能成功。
如果所有涉及到的线程没有以一致的方式来操作,那么“锁”就是没有意义的。

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
44 [报告]
发表于 2011-11-23 18:06 |只看该作者
本帖最后由 asuka2001 于 2011-11-23 18:07 编辑

这个LZ是为了研究多线程的调度,倒没必要这么要求,只是觉得这种用法很谋杀脑细胞啊 :)

假设在LZ的系统上线程先创建,必定先执行,简单起见,只模拟3个线程A, B, C,以";"作为系统调度表示。

如果有黄色的sleep:

1. lock A, 输出 A, sleep; lock B, 输出 B, sleep; lock C, 输出C, sleep;
输出为ABC

2. unlock B, lock A阻塞; unlock C, lock B, 输出B, sleep; unlock A, lock C, 输出C, sleep;

3. lock A, 输出A, sleep;
输出为BCA

下次的话B先, 但是A还没给它解锁, 所以输出为CAB....


上次提出的那个模拟的确没考虑红色sleep的情况,这个还得再琢磨,让我更头痛了。

不过那是按照顺序调度想的,第2次B之所以先运行是因为它先进sleep,C其次,A是最后进sleep的;所以调度B先执行应该是符合顺序调度的。

这个LZ提供点程序运行结果吧,我已经解释不通了,还是看实际结果得了。

论坛徽章:
0
45 [报告]
发表于 2011-11-23 18:08 |只看该作者
这个LZ是为了研究多线程的调度,倒没必要这么要求,只是觉得这种用法很谋杀脑细胞啊 :)
asuka2001 发表于 2011-11-23 18:06

关键是线程锁,根本不是这样使用的。

论坛徽章:
0
46 [报告]
发表于 2011-11-24 09:24 |只看该作者
回复 43# digdeep126

你刚开始说的哪个线程加锁必须得由自己释放自己的锁肯定是错的,你后面说的一致的方式应该指锁的类型,这里都是一个类型的锁,没问题。我想了下过程大致如下:首先循环后六个线程同时都用自己的锁锁上打印这个动作,打印出abcdef,这个顺序只跟调度有关,打印后由于都锁着,所以阻塞。然后其中有个程序首先释放了一个锁,导致下一个线程阻塞停止,能后打印了,由此往后,最终有序输出。就向之前那个ubuntu的哥们给出的结果那样,首先无序,最终有序,但不一定是abcdef的序,由“首先”是谁来决定。至于为什么不是第二次后就有序了,我想,应该是之前红色标记的“同时”那里出的问题,实际上很有可能a释放b的锁的时候b还没加锁,导致未定义行为,导致乱许几次,但毕竟这种概率小,所以几次后最终有序。我试验了,加一个sleep,前几次乱许,后面最终有序,很多次试验都是如此。

论坛徽章:
0
47 [报告]
发表于 2011-11-24 09:41 |只看该作者
回复 46# 埋头苦编
你这个例子完全是你自己杜撰出来的。对吧?你给我举个例子,来证明我说的是错误的!
你想一想下面这个场景:两个线程A, B,一把锁mutex,实现两个线程互斥地访问共享变量 n;
首先线程A加锁lock(mutex),然后操作n(假设这个操作需要较长的时间);这个时候线程B可以将线程A加在mutex上的锁释放掉???你再想想吧!兄弟。

论坛徽章:
0
48 [报告]
发表于 2011-11-24 09:53 |只看该作者
回复 46# 埋头苦编
你去查一查pthread_cleanup_push / pthread_cleanup_pop 这两个个函数最常用的功能是什么?
最常用的场景:
线程A,对mutex加锁 lock(mutex),然后主线程pthread_cancel(A),将线程A取消掉了。注意:这个时候mutex被线程A锁住了!!!那么pthread_cleanup_push的最常用的功能就是:在线程A中注册一个清理函数clean,该函数的功能就是:在线程A被取消(被pthread_cancel(A))的时候,将自己已经加在了mutex上的锁释放掉。以免其它的线程永远不能对mutex加锁成功,而造成死锁!!!
按照你的说法:其它的线程可以对“线程A加在mutex上的锁”进行释放锁的操作,那么pthread为什么还要提供pthread_cleanup_push / pthread_cleaup_pop,并且它们的最典型的作用就是在被pthread_cancel的时候对“自己加的锁进行释放(清理)”。

论坛徽章:
0
49 [报告]
发表于 2011-11-24 09:54 |只看该作者
回复 47# digdeep126
这里是6把锁,没个线程一把锁

论坛徽章:
0
50 [报告]
发表于 2011-11-24 10:00 |只看该作者
回复 1# 埋头苦编


    经过测试
俩种状态输出的都是无序的

本人的 是 4核CPU
ubuntu 10.04
gcc 4.4.3
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP