免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 10883 | 回复: 31
打印 上一主题 下一主题

[C] 线程真的很危险? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-02 11:23 |只看该作者 |倒序浏览
本帖最后由 zhendehaoren 于 2014-08-02 11:29 编辑

在看一本书中写道:
x=0;
thread1     thread2
lock;        lock;
x++;       x++;
unlock;    unlock;

虽然有锁的保护,但是如果编译器为了提高x的访问速度,会把x放到某个寄存器里,不同线程的寄存器各自独立,
还有种情况就是cpu乱序执行指令。即使加锁也不能保证线程安全。

但为何多线程大量被使用?


书上说解决方法有两个 volatile 和 barrier  但是说实话很少见用到过。

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
2 [报告]
发表于 2014-08-02 12:31 |只看该作者
编译器优化性能不会改变程序逻辑,否则就是软件bug。

CPU乱序执行不会改变程序逻辑,否则就是硬件bug。

lz贴出书名来看看。

论坛徽章:
6
酉鸡
日期:2013-11-04 15:30:02巳蛇
日期:2014-01-23 10:36:23双鱼座
日期:2014-01-23 13:08:332015亚冠之鹿岛鹿角
日期:2015-09-03 14:36:002015亚冠之武里南联
日期:2015-09-18 10:48:1315-16赛季CBA联赛之山西
日期:2016-05-05 00:05:33
3 [报告]
发表于 2014-08-02 12:33 |只看该作者
找本好书看吧~

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
4 [报告]
发表于 2014-08-02 12:34 |只看该作者
这书有问题

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
5 [报告]
发表于 2014-08-02 13:05 |只看该作者
回复 4# hellioncu


    这书没问题。。。

加volatile是对的,
禁止将变量优化到寄存器。

简化化就是这样的情况:
  1. load r0,x
  2. lock
  3. inc r0;
  4. store r0,y; 取全局x值。 但事实上被优化成直接使用r0了,
  5. ulock
  6. store r0,x
复制代码
加了volatile后是这样

  1. lock
  2. load r0,x
  3. inc r0;
  4. store r0,x
  5. store r0,y; 取全局x值。 因为有了volatile和Lock,++不会丢失。
  6. ulock
复制代码

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
6 [报告]
发表于 2014-08-02 13:14 |只看该作者
folklore 发表于 2014-08-02 13:05
回复 4# hellioncu


加了锁就没事了,不必再用volatile,也无需额外的barrier。
没有锁,只用volatile是有问题的

论坛徽章:
0
7 [报告]
发表于 2014-08-02 13:31 |只看该作者
书名是 程序员自我修养

它是windows和linux参合在一起讲的,可能说的是window下的情况

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
8 [报告]
发表于 2014-08-02 13:38 |只看该作者
回复 6# hellioncu


    我的理解,他那个lock不是汇编的lock, 只是OS的API 或是用户态的lock。
这个lock是不会更新寄存器的, 也就是变更被“地方化”了。
volatile是用来禁止变量优化到寄存器的。
同时加volatile和lock才是逻辑上正确的,
不过大多数情况下只加lock不加volatile也没事,
但这只是“碰巧”而已,
因为CPU寄存器太少了, 就算不加volaitle,
变量也没有机会被优化成前面的情形。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
9 [报告]
发表于 2014-08-02 13:52 |只看该作者
本帖最后由 csumck 于 2014-08-02 13:52 编辑

同意8楼,但是volatile不能完全解决问题,尤其时现在生产环境很多是多CPU环境.
还是要靠barrier, 不加barrier没有出错只是碰巧而已.
我曾经有个多线程的程序,线程A初始化变量x,然后线程B设置变量x,然后线程A又去读取变量x,执行顺序完全没问题,但是在某些机器上线程A最后读取变量x时就有机会读到一个错误的值.加了barrie就正常了.

论坛徽章:
0
10 [报告]
发表于 2014-08-02 13:58 |只看该作者
怕的就是这种碰巧,之前写的多线程程序有时好好的就挂掉了,死活找不到原因,从逻辑上看一点问题没有,很可能就是这些细节导致的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP