[多线程] Python 多线程的锁为什么不好用?

2019-07-02 10:08:25 +08:00
 AILOVEU

各位看官不要纠结这段代码的作用。。。 这段代码中有两个注释,加注释和不加注释为什么不一样?


import threading
import time
def  producer():
    while True:
        time.sleep(0.2)
        lock.acquire()
        print('producer acquire lock')
        time.sleep(0.1)
        time.sleep(0.1)
        print('producer release lock')
        lock.release()

def consumer():
    while True:
        time.sleep(0.1)
        #lock.acquire()
        print('consumer eating')
        #lock.release()
if __name__ == "__main__":
    lock = threading.RLock()
    t1 = threading.Thread(target=producer, args=())
    t2 = threading.Thread(target=consumer, args=())
    t1.start()
    t2.start()
    t1.join()
    t2.join()

加注释运行结果:


consumer eating
producer acquire lock
consumer eating
consumer eating
producer release lock
consumer eating
consumer eating
producer acquire lock

不加注释运行结果:


consumer eating
producer acquire lock
producer release lock
consumer eating
consumer eating
producer acquire lock
producer release lock

我觉得加不加注释都应该是 “不加注释运行结果”,

即 producer 获取 lock 后,没有释放前,consumer 为什么还运行

3149 次点击
所在节点    Python
12 条回复
lihongjie0209
2019-07-02 10:19:06 +08:00
这段代码也是牛逼, 所有入口持有一把锁, 不管你几个线程都只能串行, 线程越多性能越差
fuxiuyin
2019-07-02 10:30:31 +08:00
加注释的话,consumer 运行又没有任何限制,为啥要等 producer 释放锁呀。
ilyh
2019-07-02 10:31:50 +08:00
没毛病啊, 不加注释:consumer 先获取到锁, 然后 producer 再获取到锁,
geelaw
2019-07-02 10:35:34 +08:00
我假设你说的“不加注释”的意思是“不注释掉 consumer 拿锁的两行”。

成语:掩耳盗铃。
krixaar
2019-07-02 10:48:42 +08:00
加注释:consumer 的运行和 lock 这个锁无关,因此 consumer 的运行和 lock 这个锁无关。

不加注释:consumer 的运行受到 lock 这个锁的限制,因此 consumer 的运行受到 lock 这个锁的限制。

综上:尼克杨问号.jpg
Gakho
2019-07-02 11:24:02 +08:00
不太明白,LZ 是想要 Barrier 或者 Condition 的功能?
Trim21
2019-07-02 11:27:44 +08:00
消费者和生产者用的同一把锁,不注释的情况下,生产者锁没释放消费者拿不到,肯定在 acqure 和 release 之间不会 eat 啊
wevsty
2019-07-02 11:31:34 +08:00
threading.RLock() 只会导致在已经被加锁的情况下再 lock 同一个锁的时候才会阻塞试图 lock 的线程。
decemberpei
2019-07-02 11:46:51 +08:00
楼主对 lock 理解有误。lock 的意思是,如果 A 拿到了 lock,这个时候如果 B 也尝试拿,那么 B 就会被 block 住,直到 A 释放了 lock,B 才能拿到 lock 并恢复运行。
加了注释的情况下,B 根本没用尝试拿 lock,当然不会被 block 住,
krixaar
2019-07-02 11:47:05 +08:00
> lock 不阻塞线程吗?

阻塞线程的是 lock.acquire()这一句,注释掉之后就不阻塞了,因为代码里都没提到 lock。
weyou
2019-07-02 13:19:36 +08:00
@lihongjie0209 实际应用中只会对临界资源加锁,这只是一个多线程锁的例子,没毛病。
zkqiang
2019-07-03 18:33:34 +08:00
加了注释 consumer 肯定无限循环啊,都跟 lock 没关系了,为啥会跟不加注释一样呢?
好奇楼主咋想的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/579192

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX