关于锁和信号量的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
gino86
V2EX    程序员

关于锁和信号量的问题

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

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

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

    第 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     Solana     2841 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 13:51 PVG 21:51 LAX 06:51 JFK 09:51
    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