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

关于锁和信号量的问题

  •  
  •   gino86 · 2017-12-16 10:43:06 +08:00 · 3481 次点击
    这是一个创建于 2534 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在多线程编程中的线程同步机制一直都不是很了解(锁和信号量),我的理解是:
    被上锁的资源每次只能有一个线程可访问(互斥);
    而信号量是限制资源可同时访问的线程数。

    那么问题是,以生产者消费者为例子,如果有一个生产者和多个消费者,在只使用信号量的情况下,是否会出现消费者之间消费了相同资源的情况。

    第 1 条附言  ·  2017-12-16 12:18:10 +08:00
    其实有这个问题,是因为看了《 Java 7 并发编程实战手册》
    里面其中有一个例子在处理并发的时候,是混合使用锁和信号量同步数据的。
    而在网络上的文章中,基本上很少有这种例子。
    其中让我印象最深刻的例子是:一个厕所一把钥匙和多个厕所多把钥匙的例子,不过,当然也有人反驳这个例子。
    我个人认为作为理解的帮助也未尝不可的。
    15 条回复    2017-12-18 08:12:11 +08:00
    xwander
        1
    xwander  
       2017-12-16 11:01:19 +08:00
    搜索关键字:原子操作、自旋锁、信号量、互斥体、顺序锁
    vegito2002
        2
    vegito2002  
       2017-12-16 11:03:17 +08:00   ❤️ 1
    初始值是 1 的信号量本身就可以当做一个锁使用, 所以三个信号量就行了(empty, full, mutex), 对 buffer 进行 add/remove 的操作用 mutex 包起来. 没有这个锁就有竞争, 因为 buffer list 本身是共享的.
    CRVV
        3
    CRVV  
       2017-12-16 11:35:38 +08:00
    这不是一个简单的问题,如果一直都不是很了解,来 V2EX 上问也不可能了解
    老老实实认认真真去看教科书才是正道
    honeycomb
        4
    honeycomb  
       2017-12-16 11:38:13 +08:00 via Android
    semaphore 的语源是船上的旗语
    iyangyuan
        5
    iyangyuan  
       2017-12-16 11:57:47 +08:00   ❤️ 1
    信号量并不等于线程数,仅仅表示可用资源数量,比如生产了 4 个资源,对应释放 4 个信号量,我可以用 2 个线程去申请信号量,只申请不释放,当无信号量可用的时候,表示资源消费完毕,自动进入阻塞状态,等待新的信号量。不可能有多少资源,就创建多少线程。个人见解,仅供参考。
    Shura
        6
    Shura  
       2017-12-16 12:02:45 +08:00
    你可以使用多个信号量同步进程
    gino86
        7
    gino86  
    OP
       2017-12-16 12:12:20 +08:00
    @CRVV 书看过了,网络上的文章也看过,越看越混乱。不过觉得 v 友们是有智慧的人,所以就想请教大家
    wweir
        8
    wweir  
       2017-12-16 12:16:34 +08:00 via iPhone
    看完几本经典之后,现在的疑问是,你说的信号量是指哪个信号量的实现
    gino86
        9
    gino86  
    OP
       2017-12-16 12:20:45 +08:00
    @wweir java 中只有一种信号量,当然我也不知道它实现的是什么信号量。
    vegito2002
        10
    vegito2002  
       2017-12-16 12:21:41 +08:00   ❤️ 1
    理解这些同步 mechanism 最好的办法还是看代码. 很多 semaphore/lock/condition 实现的源代码并不复杂, OSTEP 这样的教科书里面也有类似的实现. 看完代码其实很多问题并不难理解, 这种东西本身就不适合从特别高的层面去抽象理解, OS 课程逼着学生去做 lab 不是没有原因的, 纸上得来终觉浅.
    CRVV
        11
    CRVV  
       2017-12-16 17:35:50 +08:00   ❤️ 1
    最初的的问题,能不能只用信号量。锁就是容量 1 的信号量,所以只用信号量当然可以把代码写对,但实际有没有写对那是另一回事了。

    如果是为了学写代码,那我觉得 "An Introduction to Programming with Threads" 写得很通俗。

    如果是为了实现生产者消费者这种模型,建议用 Java 的 BlockingQueue,Python 的 queue.Queue 或者 Go 的 channel,会非常简单。用信号量之类的东西要难写得多。
    jimzhong
        12
    jimzhong  
       2017-12-16 21:26:57 +08:00   ❤️ 1
    不会。
    信号量是一个比较高级的同步机制。
    信号量的实现一般依赖于锁。
    信号量和线程数没有必然关系。
    oaix
        13
    oaix  
       2017-12-16 21:58:40 +08:00
    生产消费者模型还需要一个叫做“条件变量” 的东西,只有锁是不够的。
    gino86
        14
    gino86  
    OP
       2017-12-18 08:08:50 +08:00
    @oaix 在 Java 中条件变量只是其中一种同步机制,条件变量对生产者消费者模型不是必须的
    gino86
        15
    gino86  
    OP
       2017-12-18 08:12:11 +08:00
    @CRVV 嗯,这个我知道,线程安全的集合在编程手册中有提及
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   971 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 20:21 · PVG 04:21 · LAX 12:21 · JFK 15:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.