[問題] thread-safe queue

看板Python作者 (suhang)時間6年前 (2019/04/26 04:02), 6年前編輯推噓4(4010)
留言14則, 2人參與, 6年前最新討論串1/3 (看更多)
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://www.ptt.cc/bbs/Python/M.1556222522.A.941.html

04/26 06:22, 6年前 , 1F
我不確定 但我覺得應該是你這樣每次wake get() put()
04/26 06:22, 1F

04/26 06:23, 6年前 , 2F
同時被wake一次? 然後如果 2 condition get()->
04/26 06:23, 2F

04/26 06:27, 6年前 , 3F
阿說錯 put()只需要notify get() 因為你在 len(que)
04/26 06:27, 3F

04/26 06:28, 6年前 , 4F
>= cap: wait 的時候 只有當len(que)< cap 才會放出
04/26 06:28, 4F

04/26 06:29, 6年前 , 5F
LOCK, 這時候你的len(que) = cap - 1. 然後你在que.
04/26 06:29, 5F

04/26 06:30, 6年前 , 6F
append 這時len(que) = cap, 你只需要叫get(), 因為
04/26 06:30, 6F

04/26 06:31, 6年前 , 7F
你叫put他只會繼續入睡(len(put) = cap)
04/26 06:31, 7F

04/26 06:31, 6年前 , 8F
如果有錯請指正XD
04/26 06:31, 8F
很抱歉 沒能很清楚的了解你的意思 如果我只有一個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

04/26 08:30, 6年前 , 9F
size=1的時候, 2個thread去get, 一個卡wait, 一個過了
04/26 08:30, 9F

04/26 08:31, 6年前 , 10F
condition相同, 過了的那個 nottify到 wait的那個, 然後?
04/26 08:31, 10F
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

04/26 11:30, 6年前 , 11F
size=Full. Ta, Tb: put and wait. T1: get and sig(Ta).
04/26 11:30, 11F

04/26 11:30, 6年前 , 12F
T2: put and acquire first then Ta, Tb, finally sig(Tb)
04/26 11:30, 12F

04/26 11:30, 6年前 , 13F
Ta, Tb wait and put, size overflow.
04/26 11:30, 13F

04/26 11:37, 6年前 , 14F
更正, 不需要T2. Ta wake and sig(Tb). 就炸了
04/26 11:37, 14F
抱歉,我看得更糊塗了 現在只有一個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
文章代碼(AID): #1SmX8wb1 (Python)
文章代碼(AID): #1SmX8wb1 (Python)