作者suhang (suhang)
看板Python
标题[问题] thread-safe queue
时间Fri Apr 26 04:01:59 2019
https://paste.ubuntu.com/p/cWsFNYcGpQ/
先写了MyQueue1 用一个condition
consumer thread透过condition判断que empty ,就wait, release lock
producer thread透过同一个condition 取得lock, 放东西到que, and notify consumer
但是看了python and java source code
都是用两个condition (not_empty / not_full)
为什麽要这麽做呢?我的作法应该也行得通,难道是效率问题?
看不透,请大家解疑,感谢
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 76.169.162.97
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Python/M.1556222522.A.941.html
1F:推 benchen0812: 我不确定 但我觉得应该是你这样每次wake get() put() 04/26 06:22
2F:→ benchen0812: 同时被wake一次? 然後如果 2 condition get()-> 04/26 06:23
3F:→ benchen0812: 阿说错 put()只需要notify get() 因为你在 len(que) 04/26 06:27
4F:→ benchen0812: >= cap: wait 的时候 只有当len(que)< cap 才会放出 04/26 06:28
5F:→ benchen0812: LOCK, 这时候你的len(que) = cap - 1. 然後你在que. 04/26 06:29
6F:→ benchen0812: append 这时len(que) = cap, 你只需要叫get(), 因为 04/26 06:30
7F:→ benchen0812: 你叫put他只会继续入睡(len(put) = cap) 04/26 06:31
8F:→ benchen0812: 如果有错请指正XD 04/26 06:31
很抱歉 没能很清楚的了解你的意思
如果我只有
一个condition variable
Producer (P1) 先透过with self.condition 取得self.lock
刚进入while检查是否有空间。
若此时Consumer(C1) 要读取,透过self.condition想取得lock,
发现无法进入,因为self.lock被P1使用中,因此等在那儿
当P1检查空间,发现满了,无法放入新的item, 於是wait()也release lock
这时候等在那边的C1 取得lock,开始做while 判断是否有东西可以取得
我想,只有单一condition的情况,我的程式应该没问题
但是如果有
两个condition, not_empty & not_full
按照Python Queue source code的注解
https://paste.ubuntu.com/p/5P3dZ35yt4/
这两个condition共同使用同一个lock
按照注解的写法,
我感觉是能够同时达到一边读一边写,
但若是空了则C1 block等待,或者满了则P1 block等待
或者,这是让多个C1 C2 C3 / P1 P2 P3更有效率?
我不是很懂怎麽运作的
我也不知道我的理解对了几成
现在正疯狂搜索mutex / lock / signal 之类的文章找答案中...
有大神能解惑吗?
※ 编辑: suhang (76.169.162.97), 04/26/2019 07:52:06
9F:推 Yshuan: size=1的时候, 2个thread去get, 一个卡wait, 一个过了 04/26 08:30
10F:→ Yshuan: condition相同, 过了的那个 nottify到 wait的那个, 然後? 04/26 08:31
que size = 1
if only has one self.condition
c1 consuming,
c2 blocked and waiting
c1 notify and release lock
c2 get lock and check while loop
que size = 0, c2 wait()
如果只有单一condition, 不会有bug吧?
ps 如果不是用while loop 而是用 if 检查 que size, 就会出问题了
※ 编辑: suhang (76.169.162.97), 04/26/2019 08:59:24
11F:推 Yshuan: size=Full. Ta, Tb: put and wait. T1: get and sig(Ta). 04/26 11:30
12F:→ Yshuan: T2: put and acquire first then Ta, Tb, finally sig(Tb) 04/26 11:30
13F:→ Yshuan: Ta, Tb wait and put, size overflow. 04/26 11:30
14F:推 Yshuan: 更正, 不需要T2. Ta wake and sig(Tb). 就炸了 04/26 11:37
抱歉,我看得更糊涂了
现在只有一个condition, que full
Ta, Tb: put and wait.
Ta Tb 是producer吗?
Ta Tb两个producer都在等待中
T1: get and sig(Ta).
T1领了一个item, 然後Ta正好抢到了lock
T2: put and acquire first then Ta, Tb, finally sig(Tb)
这边 T2是producer ?
Yshuan 能麻烦你回一篇吗?
ps 我还是没搞懂为什麽要用两个condition
ps ps 如果只有一个condition
que full
producer 1(p1) , producer 2(p2) 同时想要put
p1 acquire lock,
while loop: que full, p1 wait and release lock
p2 acquire lock
while loop: que full, p2 wait and release lock
大家都等在那边,不是吗?
※ 编辑: suhang (76.169.162.97), 04/26/2019 12:09:33