多个线程对一个内建类型的变量做赋值是否需要加锁?

uuussseeennn 2010-03-03 05:49:15
加精
举例:
int i = 0; // 全局变量

// 此函数会被多个线程调用
void add(int j)
{
i += j;
}

问题:
(1) 在进行i += j操作时是否需要加锁?为什么?
(2) i += j;在不同的平台下是否会被编译成不同的汇编语句?要不要加锁是否跟这个有关?
...全文
1316 71 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
71 条回复
切换为时间正序
请发表友善的回复…
发表回复
yangchuan123 2010-03-13
  • 打赏
  • 举报
回复
需要加锁,因为该语句会被翻译成至少两条汇编语句,且这些语句又不是原子操作。
uuussseeennn 2010-03-12
  • 打赏
  • 举报
回复
想不到此贴能让这么多人顶,真是出乎我意料,哈,我现在总结一下回帖人类型:
(1)学习型:不管怎样,愿意学习的都要鼓励;建议以后多了解多核多线程的知识;
(2)简单加锁型:应该接触过多线程编程,但涉入不深,未了解加锁的根本原因;没必要的加锁可能导致性能上的无谓开销,在一些核心模块,可能导致性能急剧下降。
(3)深入解析型:能从汇编和指令周期级别给与分析,应该在多核编程上已有所造诣。希望互相学习:)如sinservice。
(4)给出解决方案型:不仅知道加锁的原理和优缺点,同时能改进程序设计,绝对是我们学习的榜样。如xingzhe2001。
谢谢大家了:)
Yexi1473 2010-03-11
  • 打赏
  • 举报
回复
枷锁吧··
zhuoyue 2010-03-11
  • 打赏
  • 举报
回复
路过看看

长度补丁
jiujiang88 2010-03-11
  • 打赏
  • 举报
回复
需要加锁,防止数据的不正确性.
feilong0309 2010-03-10
  • 打赏
  • 举报
回复
dos进入windows时,从borland c++的dos版(3.1)到win版(4.x),感觉没什么太多的跃变;
看过一点vb(4?),然后就遇到了以前turbo pascal的接班人:Delphi 1.0!
从而走上不归路,15年来就没再改攻其他语言,主要是用过delphi之后的一览众山小(或者说除却巫山不是云)——当然,也许深层的原因
feilong0309 2010-03-10
  • 打赏
  • 举报
回复
dos进入windows时,从borland c++的dos版(3.1)到win版(4.x),感觉没什么太多的跃变;
看过一点vb(4?),然后就遇到了以前turbo pascal的接班人:Delphi 1.0!
从而走上不归路,15年来就没再改攻其他语言,主要是用过delphi之后的一览众山小(或者说除却巫山不是云)——当然,也许深层的原因
feilong0309 2010-03-10
  • 打赏
  • 举报
回复
在dos进入windows时,从borland c++的dos版(3.1)到win版(4.x),感觉没什么太多的跃变;
看过一点vb(4?),然后就遇到了以前turbo pascal的接班人:Delphi 1.0!
从而走上不归路,15年来就没再改攻其他语言,主要是用过delphi之后的一览众山小(或者说除却巫山不是云)——当然,也许深层的原因是个
lwtsea 2010-03-10
  • 打赏
  • 举报
回复
引用 37 楼 sinservice 的回复:
都没有说到点子上。

如果确定可以编译成一条指令,那么需要加锁么?
答案是,要看编译成什么样的指令。

在单核机器上,如果可以编译成一条指令,确实无需加锁了,因为指令执行中不会被打断,但在多核机器上,两条“对于一个内存单元”的指令同时运行在两个核上,即使考虑总线时序,但如果指令是多个周期的,就不是原子的。
结论是,在多核机器上,如果指令是单周期的,就是原子的,但如果指令是多周期的,就不是原子的。

奔腾系列x86 CPU都有指令前缀lock,描述紧跟的内存操作指令,来指定此操作对总线的独享,实现存取原子性。


觉得很有道理啊,学习了
lwtsea 2010-03-10
  • 打赏
  • 举报
回复
大家是否要考虑下cpu个数的?
ljz_761121 2010-03-10
  • 打赏
  • 举报
回复
需要。
架设i=0,j=1;
正常两个线程之行后 i = 2;
i += j分解为

tmp = i + j
i = tmp
线程1执行到 tmp = i + j, 这时线程2也执行 tmp = i + j, i = tmp,
这时1再执行i = tmp, 最后 i = 1。显然与要求的i=2不符
dqm12345678 2010-03-10
  • 打赏
  • 举报
回复
大学毕业了,很多人都失业了。
dqm12345678 2010-03-10
  • 打赏
  • 举报
回复
最近在看C++方面的书,加油!
dqm12345678 2010-03-10
  • 打赏
  • 举报
回复
c++语言好难,真不知道什么时候自己能单独写出一个程序。
paratera35 2010-03-09
  • 打赏
  • 举报
回复
呵呵,学习,学习。
好东西大家分享,值得去看看哦。
http://www.paratera.com/Article_pro.asp?channel=5&classid=6&classname=%E8%87%AA%E6%9C%89%E8%BD%AF%E4%BB%B6
观弈道童 2010-03-09
  • 打赏
  • 举报
回复
的药
每天回帖即可获得10分可用分!小技巧:教您如何更快获得可用分
白头老汉 2010-03-09
  • 打赏
  • 举报
回复
需要加互斥,总之加了不会错
yongningzh 2010-03-09
  • 打赏
  • 举报
回复
应该要加锁,以避免别的线程取得赃数值
huangchengbohuang 2010-03-09
  • 打赏
  • 举报
回复
呵呵呵呵
这个 正在学习
freeskyo 2010-03-09
  • 打赏
  • 举报
回复
多线程中,按你说这就是一个互斥量,如业务中交费实时统计当前交费总量,这个总量肯定是要加锁的。
加载更多回复(51)

567

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧