V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
pythonee
V2EX  ›  程序员

为什么多线程需要锁呢?

  •  
  •   pythonee · 2012-11-17 14:04:38 +08:00 · 6046 次点击
    这是一个创建于 4387 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我知道很多无锁的数据结构,但是这不是要讨论的
    假设我们的程序是跑在单核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   ·   实用小工具   ·   991 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 21:15 · PVG 05:15 · LAX 13:15 · JFK 16:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.