[問題] 請問 Coroutine & 一般 callback 合作的問題

作者: HuangJC (吹笛牧童)   2023-02-05 12:58:28
描述一下問題:
目前的工作我可以用 multi-thread 做到
https://paste.ee/p/0oAqf
執行結果:
03:16:44: do 1
notify
03:16:45: do 2
do 1 是 thread1 會動的證明,然後用 condition 塞住自己
notify 代表 thread2 利用 condition 通知 thread1
然後 do 2 代表 thread1 果然解鎖了,繼續執行
如果要改成用 Coroutine 做,我也做得到
https://paste.ee/p/BiPJp
結果是一模一樣的(除了時間不一樣)
注意到,和 multi-thread 的版本相比
condition 不能在全域的地方產生了
不然會有一個錯誤訊息,說是不能使用不同 loop 的東西
改用 Coroutine 寫也一樣,只是 condition 改用 asyncio 的版本
這還難不倒我,也算一想就通
因為它們不是真正的 thread
我知道 python 的 multi-thread 不算真正的 thread
但不影響我討論,對吧!
附上兩支程式,代表這程度我懂
接下來要談我不懂的
如果我在 task1 裡用 thead 版的 condition 把 task1 塞住
那 task2 也會一併塞住! 因為它們其實是同一個 thread
但我若用 asyncio 版本的 condition, 那所謂的塞住就只是交回控制權給 loop
而 loop 會再次分配給 task-2 以達到 Coroutine 的偽多工;完美~
https://paste.ee/p/U7nzP
這是用 thread 版本的 condition 把整個 Coroutine 塞住的例子
執行結果:
03:24:09: do 1
連 notify 都不會印出了,因為 task1 塞住,task2 根本就不會去執行
現在問題在,我的 task-2 若不是 async 宣告
這就是個問題,因為它本來是另一個 thread,打算改寫過來但不順利
這不是什麼簡單複雜化,而是我必需把專案的情境模擬成這樣
因為有某些部份是引用別人寫的 lib, 我不想去全面改寫
https://paste.ee/p/kgAsv
執行結果:
03:26:44: do 1
notify
do 1 有印出,然後 task1 塞住
thread2 要求解鎖其實也做到了
注意到我的 thread2 是呼叫 asnyc 版本的 release()
要求是有要求,但 task1 不照辦,根本不會收到 notify!!!!
所以現在是 task-1 & thread-2 之間的 condition 控制問題了
難道我必需全面棄用 thread, 一定要把 thread-2 改寫成 task-2?
問題就在 condition.notify_all() 不會有預期的效果
但如果用 multi-thread, 我是輕易能做好這些事的
像這樣要怎麼讓 condition 正常的運作起來呢?
謝謝
作者: lycantrope (阿寬)   2023-02-05 14:34:00
看不太懂你想要問什麼...
作者: surimodo (好吃棉花糖)   2023-02-05 15:36:00
你進公司前都沒碰python嗎公司也很敢給你什麼不會的弄主架構
作者: s9041200 (小明阿)   2023-02-05 16:02:00
epoll?
作者: Faker0613 (月巴月巴)   2023-02-05 16:09:00
Python的thread也不是真的multi啊 會有coroutine 就是要改善cpu 使用效率問題Async create_tash勒 我實在不知道你要幹嘛
作者: TakiDog (多奇狗)   2023-02-05 18:49:00
簡單複雜化? 看不懂了 建議你重學os
作者: lycantrope (阿寬)   2023-02-06 11:04:00
用asyncio.to_thread?
作者: gomi (勾億郎)   2023-03-18 23:02:00
你是不是想用 multi processing?
作者: firejox (Tangent)   2023-04-18 13:00:00
loop.call_soon_threadsafe

Links booklink

Contact Us: admin [ a t ] ucptt.com