→ surimodo: 叫老闆升級CPU 01/29 23:13
這太暴力了 XD,整個專案成本都會上升
目前用 RPI 3B+
推 poototo: GIL下,thread本來就是互斥的 01/29 23:18
→ poototo: 客製互斥鎖沒有改變thread互斥性,只會影響公平性 01/29 23:19
因為我也只抱怨公平性 XD,但我發現做不來
比如 thread 1, 然後 thread 2, 然後 thead 3 ; 這是我手工打造的順序且全速執行
如果 thread 1 裡有個 sleep 我得自己去改寫,
因為這時它會空等,沒讓 thread 2 趁機先跑
sleep 是我自己下的,全域搜尋並改寫不難
但如果是操作低速硬體,這時多出來的 CPU 效率可以給 thread 2 先跑
這我改寫不出來;因此我有在想同時允許兩個 thread 跑
→ poototo: 可試試Coroutines&Tasks,管理成本比thread低很多 01/29 23:19
協同式多工?我想到很久前寫 windows 的 message loop 的經驗
我好像就正在手工打造 coroutines,得比比官方的輪子怎麼用
→ TakiDog: 當今天出現sleep 應該要思考流程設計 01/30 01:49
→ TakiDog: asyncio.sleep 會更好的去釋放資源 01/30 01:52
→ TakiDog: 你大可一個設備一個process溝通,資料再彙整到一處 01/30 01:53
https://ithelp.ithome.com.tw/articles/10262385
看了這個才理解大家說的 task
剛還去 google task vs process, 因為我搞混了兩個詞
看來一個可執行檔跑起來,叫做 process
而一個可被執行的程式片段,叫做 task
推 timsheu: asyncio效能比multi-thread好很多,但語法要熟悉一下 01/30 09:29
→ timsheu: multi-process的話,若資料要互通要用share memory 01/30 09:30
→ timsheu: 官方的asyncio用不習慣的話,也可以用trio,比較容易上手 01/30 09:32
→ timsheu: asyncio要注意一下python版本,有些語法只適用python3.8+ 01/30 09:34
→ timsheu: 我是用rpi4b架fastapi,python3.7,asyncio+rxpy 01/30 09:35
推 timsheu: asyncio要同時跑coroutine的話,要包成task才行。 01/30 09:40
→ day831231: 假設只有一個CPU 01/31 06:32
→ day831231: 那用thread 跟 process 速度不會差到太多 01/31 06:32
→ day831231: 感覺只是使用方式錯誤 01/31 06:32
在 C 是這樣,在 python 因為有 GIL,它的 thread 是閹割的...
我曾想 GIL 是不是一種設計上的限制,
後來發現它很大量的減少我使用 critical section,也算方便
舉例來說,一個變數如果略大,佔 8 個 byte 好了
真正的 multithread 我必需擔心當變數只更新了 4 個 byte 就被另一個 thread 參考
解決方法就是用各種同步物件去限制
但在 GIL 的閹割之下,這種事在 python 我從不擔心
CPU 當然不會更有效率,舉兩個 thread 來說,c 和 python 都是'大家平分各50%效率'
差別就在'卡卡的',比如,同時控制 x, y 軸的控制器,若 x, y 軸各用一個 thread
用 C 寫,就能完美的走斜線,用 python 寫,看網友抱怨是會抖動
現在 Coroutine, 譯為協程,看到今天感覺這東西更妙
頗有以前我寫 windows sdk 時接觸的 message loop 的感覺(事實上它生了個 loop)
我可以指定在 sleep 時才切換 cpu 到另一個 'thread'
切換時機由我指定,那我就更不擔心變數被另一個 thread 偷換掉了
我對同步的協調應該可以更少
但同樣的,一個 'thread' 卡住,就是大家都卡住,這問題又冒出來了 XD
※ 編輯: HuangJC (49.216.44.32 臺灣), 01/31/2023 06:51:57
為什麼 Coroutine 比 Multithread 有效率?我有個猜想,但不知有沒有人附議
(沒法子,我經常要去想原理,以便應用在其他地方,或用來理解 bug)
MT 需要本文切換,這是它慢的原因
而它何時切換?因為 GIL,它不會在指令執行到一半時切換。它總是執行完。
上次看到某網頁寫,它總是執行一百道 python 指令,然後切換
100 是寫在 spec 裡的或者任何一家實作 python 的廠商都可以改?我不知道
但反正它是這樣切
而 C 語言的切換是用時間,比如 100 毫秒,由 timer 發起中斷,CPU 收到中斷
配合 OS 寫好的中斷處理常式引起本文切換。因為是用時間,所以平滑多了
而一道 C 指令會譯成幾道組合語言?不清楚。每個機械碼佔用幾個機械週期?不清楚
但用 timer 由外部引起中斷,這平滑很多很多
平滑到 C 指令可能才執行一半,就被切去另一個 thread 了
Coroutine 則是本文切換由軟體工程師決定,在每個 sleep 點才切換
如果完全不寫 sleep,就會完全不切換;引起 Block XDDD
而因為切換點都在 python 肚子裡,所以也不勞動外部 timer,不勞動 OS 中斷常式
因此才能做到 Coroutine 的 'thread' 不必註冊到 OS 層級
註冊到哪級是一回事,我以為只要本文切換就是個負擔
但現在這個本文都是 python 肚子裡的事,可能會因此小點
猜是這樣猜啦...
※ 編輯: HuangJC (49.216.44.32 臺灣), 01/31/2023 07:57:50
推 Falldog: GIL卡的是python layer, C level的不會卡, eg. socket io 01/31 23:19
→ Falldog: 理論上ui會感到卡一定是main thread做太多事卡住render 01/31 23:19
→ Falldog: 用thread的話,就盡量用event queue的方式溝通 01/31 23:21
→ Falldog: 如果在main thread需要跟其他thread用lock搶資源的話 01/31 23:22
→ Falldog: 會卡似乎也是預期內的事 01/31 23:22
→ Falldog: 補充一下 GIL, C level 有機會可以 release GIL 02/01 00:44
有空我檢查一下,我不記得我 main thread 有用 lock
應該只是 31 個 thread 真的太多,拖慢了
如果用了 coroutine, 那真是把 30 個變成 task,共享一個 thread
我目前做法是觀察會變卡的東西,最明顯的就是 mainthread 每秒更新的時鐘(hh:mm:ss)
它變成兩秒跳一次,於是我把何時更新其值,設一個 watch dog
如果其值用跳的,我就開動 lock
這個 lock 就是用來鎖住 30 個設備的 thread
但目前這樣做也不會順就是了
推 poototo: PEP 703就有可能讓GIL Optional 02/01 00:52
※ 編輯: HuangJC (49.217.70.24 臺灣), 02/01/2023 09:10:48
各位太熱情了,目前我著迷在 Coroutine 了
我相信它可以解決我的問題。。。
學每個東西都需要時間,我要先決策要不要去學,然後才學
而不是學了才來決策。。。。
(我怎麼聞到自己不求上進的 fu)
不是啦,我不只是工程師,我也要想自己的成本問題啊
當我能力不足,先決策再投資生命並沒有錯!
我會先 google 一下大家提的東西,但我未必學得會,未必投資;對吧 :P
→ zerof: 左轉 pypy 02/01 16:38
→ s9041200: 試過epoll嗎? 02/01 20:10
※ 編輯: HuangJC (123.204.157.162 臺灣), 02/03/2023 12:47:28
→ gomi: cpu bound 即使異步也沒用吧 我想 09/09 20:43