为什么多线程需要锁呢? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
请不要在回答技术问题时复制粘贴 AI 生成的内容
pythonee

为什么多线程需要锁呢?

  •  
  •   pythonee Nov 17, 2012 6965 views
    This topic created in 4908 days ago, the information mentioned may be changed or developed.
    我知道很多无锁的数据结构,但是这不是要讨论的
    假设我们的程序是跑在单核cpu上的,现在有一些线程共享了某资源,问题是,我们的cpu在一次只会执行一个指令,也就是说,这些资源的读写如果是原子的话,也就是如果读写只是一条cpu指令的话,那么是不是就意味着不需要锁了,因为,这些线程争用cpu,但是cpu保证每次都只有一个指令的运行,cpu本身是串行的了,是这样的吗
    16 replies    1970-01-01 08:00:00 +08:00
    qq286735628
        1
    qq286735628  
       Nov 17, 2012
    但实际上一个高级语言的一句读写操作,已经是跑在多个CPU时钟周期了~除非是单片机那种底层语言
    reus
        2
    reus  
       Nov 17, 2012
    是的,操作是原子的就不需要锁了。不过很多操作都需要很多条机器指令,不是原子的,所以需要锁来保证
    Muninn
        3
    Muninn  
       Nov 17, 2012
    你这问题问的有点哗众取宠
    在内容里才限定了一个cpu
    不过即使如此
    楼上也都回答了。。。
    BigZ
        4
    BigZ  
       Nov 17, 2012
    支持多线程,多进程的操作系统,在做切换的时候,会保留各种context,cpu切回来之后,会还原原有状态,于是在每个线程/进程眼里,各自都是独占了一个cpu
    clino
        5
    clino  
       Nov 17, 2012
    即使是单核cpu,只要操作系统是抢先式任务调度的,那一样需要锁的

    "cpu保证每次都只有一个指令的运行,cpu本身是串行的了"
    即使"读写只是一条cpu指令"一样可能会产生race condition.
    nodenode
        6
    nodenode  
       Nov 17, 2012
    @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  
       Nov 17, 2012
    你没有考虑Critical Section的大小。
    guoxx_
        8
    guoxx_  
       Nov 17, 2012
    以singleton模式为例子

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

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

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

    就像我们平时排队买东西一样,轮到你却没货了,你就要么放弃要么等人家上货。
    chisj
        14
    chisj  
       Nov 17, 2012
    和CPU多少无关,是因为每个线程只能执行一个时钟周期,执行完一个时钟周期就被切换,其他线程得到资源。话说这个教材里讲得非常清楚了啊!
    funcman
        15
    funcman  
       Nov 17, 2012
    错。
    这跟CPU是串行还是并行无关。即使是串行,两个线程的时间片还是乱序的。
    同步就是要保证一定的次序。
    shuizhuzi
        16
    shuizhuzi  
       Nov 18, 2012
    这这……不能这样比,不一个层次啊
    一个是硬件层,一个是系统层……
    About     Help     Advertise     Blog     API     FAQ     Solana     5965 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 72ms UTC 03:19 PVG 11:19 LAX 20:19 JFK 23:19
    Do have faith in what you're doing.
    ubao msn 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