为什么多线程需要锁呢? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI生成的内容
pythonee
V2EX    程序员

为什么多线程需要锁呢?

  •  
  •  pythonee 2012-11-17 14:04:38 +08:00 6547 次点击
    这是一个创建于 4712 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我知道很多无锁的数据结构,但是这不是要讨论的
    假设我们的程序是跑在单核cpu上的,现在有一些线程共享了某资源,问题是,我们的cpu在一次只会执行一个指令,也就是说,这些资源的读写如果是原子的话,也就是如果读写只是一条cpu指令的话,那么是不是就意味着不需要锁了,因为,这些线程争用cpu,但是cpu保证每次都只有一个指令的运行,cpu本身是串行的了,是这样的吗
    16 条回复    1970-01-01 08:00:00 +08:00
    qq286735628
        1
    qq286735628  
       2012-11-17 14:07:48 +08:00
    但实际上一个高级语言的一句读写操作,已经是跑在多个CPU时钟周期了~除非是单片机那种底层语言
    reus
        2
    reus  
       2012-11-17 14:11:15 +08:00
    是的,操作是原子的就不需要锁了。不过很多操作都需要很多条机器指令,不是原子的,所以需要锁来保证
    Muninn
        3
    Muninn  
       2012-11-17 14:15:51 +08:00
    你这问题问的有点哗众取宠
    在内容里才限定了一个cpu
    不过即使如此
    楼上也都回答了。。。
    BigZ
        4
    BigZ  
       2012-11-17 14:34:41 +08:00
    支持多线程,多进程的操作系统,在做切换的时候,会保留各种context,cpu切回来之后,会还原原有状态,于是在每个线程/进程眼里,各自都是独占了一个cpu
    clino
        5
    clino  
       2012-11-17 14:42:13 +08:00
    即使是单核cpu,只要操作系统是抢先式任务调度的,那一样需要锁的

    "cpu保证每次都只有一个指令的运行,cpu本身是串行的了"
    即使"读写只是一条cpu指令"一样可能会产生race condition.
    nodenode
        6
    nodenode  
       2012-11-17 16:29:41 +08:00
    @reus 正解

    另外,多核情况下x86架构可以在单指令中使用lock选项来防止其它核访问内存:
    http://wiki.osdev.org/Atomic_operation

    linux kernel里已经给这些单指令做了包装,屏蔽了不同架构下的差异,直接使用那些atomic_XXX函数就可以进行原子操作了:
    http://www.ibm.com/developerworks/cn/linux/l-linux-synchronization.html
    liuw
        7
    liuw  
       2012-11-17 16:43:51 +08:00
    你没有考虑Critical Section的大小。
    guoxx_
        8
    guoxx_  
       2012-11-17 17:23:37 +08:00
    以singleton模式为例子

    void *getSingletion(){
    if(NULL == instance){
    instance = malloc(10086);
    bzero(instance, 10086);
    }
    }

    如果没有锁,会发生什么情况?
    所以多线程就不要锁 和几个cpu没有关系
    guoxx_
        9
    guoxx_  
       2012-11-17 17:47:34 +08:00
    // 上面手误打错了
    所以多线程就要锁 和几个cpu没有关系
    pythonee
        10
    pythonee  
    OP
       2012-11-17 18:21:16 +08:00
    @Muninn 是吗,但是我觉得多核讨论这个问题意义不大,我这几天编写多线程程序多了之后,突然想到这个问题,当然,可能更好的问题是如何避免锁
    lesscome
        11
    lesscome  
       2012-11-17 20:30:37 +08:00
    多线程操作公共数据,锁是不可避免的,lz不如想想怎么降低锁带来的资源消耗。
    Ricepig
        12
    Ricepig  
       2012-11-17 21:40:23 +08:00
    锁的主要问题是容易造成不必要的等待,极端就是死锁。锁并不一定就低效的
    darasion
        13
    darasion  
       2012-11-17 21:44:53 +08:00
    锁的本质是队列。

    你把所有有竞争关系的东西,放进一个队列里。就不会冲突了。

    就像我们平时排队买东西一样,轮到你却没货了,你就要么放弃要么等人家上货。
    chisj
        14
    chisj  
       2012-11-17 21:49:01 +08:00
    和CPU多少无关,是因为每个线程只能执行一个时钟周期,执行完一个时钟周期就被切换,其他线程得到资源。话说这个教材里讲得非常清楚了啊!
    funcman
        15
    funcman  
       2012-11-17 23:39:11 +08:00
    错。
    这跟CPU是串行还是并行无关。即使是串行,两个线程的时间片还是乱序的。
    同步就是要保证一定的次序。
    shuizhuzi
        16
    shuizhuzi  
       2012-11-18 00:22:40 +08:00
    这这……不能这样比,不一个层次啊
    一个是硬件层,一个是系统层……
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     6066 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 02:30 PVG 10:30 LAX 19:30 JFK 22:30
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86