Re: [問題] py程式之間的值如何傳遞
謝謝你的討論,我好像看到適合我的東西 XD
我的例子是我要寫出 sensor(比如讀取溫度計)
還有另外寫出使用 sensor 值運作的程式
socket 我會寫,但處理斷線,timeout 的邏輯累死我了
後來我用 mqtt
除掉處理斷線,timeout 等等問題
這種類似 call back 的邏輯給我另一種困擾, 比如
sensor.py 送出溫度計值
然後 relay.py 就必需接收到這個值處理起來
但其實我不在乎溫度計何時傳值給我
我在乎的是最後一個值是什麼
比如五秒有五次更新值,反正我在第五秒才想處理
那前四次的值其實我不在乎,就讓它消失吧..
用 mqtt 其實我就是在收到訊息時,on_message 自己維護一塊記憶體先塞進去
何時要用此值,才去問那塊記憶體
檔案可以擔此重任,用覆蓋的就好
但不同程式間 multitask, 就不要寫入端開檔/清空,還沒寫入,讀取端就來讀耶
那我又有其他困擾了
》何時要用此值,才去問那塊記憶體
Redis 不就替我做了這事
而且可以跨電腦
檔案的話,不知有沒有一定要關檔(所以保證寫入完畢),其他程式才能開檔的檢查
這問題在 multi-thread 裡即使是記憶體變數,也是很常面對的
但用 python 我一直都不用理,因為 python 的多工有個 GIL 在,它的 ATOM 太大了
若在 C,我就吃了不少虧,常常要設 critical section
而 Redis 應該就是跨電腦很適合吧..
當有多台電腦跑 relay.py,
他們何時需要資料,就何時去問 sensor.py 那台電腦
而不是 sensor.py 經常主動推播,漏收訊息也不好
不想收,它也一直推給所有來註冊的電腦
(喔,mqtt 採訂閱制,不想收就不訂閱,困擾沒那麼大)
很值得我參考。
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.204.157.162 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/Python/M.1674701472.A.C2B.html
補上檔案的問題
from time import sleep
file = 'output.txt'
with open(file, 'w') as f:
f.write('apple\n')
sleep(10)
f.write('banana\n')
這個例子是個極端做法,在寫檔中間插入等待十秒
在做 multi-thread/task 極端 debug 時,有時得這麼做
我們知道寫檔很快,但萬一沒那麼快時,有沒有問題?
開啟兩個 terminal, 一個用命令列執行這個程式
(比如 python3 test.py)
要十秒後,游標才會掉下來
這時趕快去另一個 terminal 試 cat output.txt
十秒內,檔案已經存在,但內容是空的
-------------
以前學微軟的 SDK 時,關於開檔,有更多參數可下
share read/write 限制等等
如果我不開 share, 基本上就是不共享了
(不知有沒有記錯;頂多記反,但確定有這個概念)
不共享的意思是,當有一個程序開了此檔做寫入
那麼別人就無法做讀取
那這個 bug 也就不會發生
不然若我用檔案當做 IPC 中介傳遞,在 a.py 寫入時,恰好 b.py 要讀取
那就會讀到空檔,怎麼辦?
當然這狀況很難發生,因為檔案並不會寫到十秒那麼久
但如果是一萬次發生一次,也會讓人頭疼,bug 重製不易
所以刻意改變執行速度也是個技巧
要說我龜毛嗎?
※ 編輯: HuangJC (49.217.46.86 臺灣), 01/26/2023 16:02:43
→
01/26 15:58,
1年前
, 1F
01/26 15:58, 1F
抱歉,看不懂,可以給多一點資訊嗎?謝謝
https://bbs.huaweicloud.com/blogs/325805
是像這個例子嗎?
這例子不是我要的
它可以在檔案改變時觸發 event
於是就好像 call back
call back(或說 interrupt)的確有時對我有用
但比如有個溫度計,sensor.py 每一秒去讀它一次
我並不在乎何時讀了並更新到 output.txt 裡
我在乎的是,另一支程式,relay.py 要去取用檔案裡的溫度值時
任何時候,我想讀,就有目前的值;我只要最後一個值而已
因此新值不斷覆蓋舊值,我不在乎
但我在乎檔案寫到一半不能被讀取時,很恰巧的我去讀了...
所以我需要一些像是 critical section 這樣的東西
但我想 redis 有做好這件事
※ 編輯: HuangJC (49.217.46.86 臺灣), 01/26/2023 16:15:03
舉個例子,共享的若是一個溫度值,int or float, 問題不大
但若是一張相片,檔案還真不小,寫入需要時間,那問題就出來了
當然或許可以用寫入 tmp file 然後 rename 的方式,減少空窗期
但還是有點機率去讀到空圖。。
※ 編輯: HuangJC (49.217.46.86 臺灣), 01/26/2023 16:18:12
https://myapollo.com.tw/zh-tw/python-fcntl-flock/
找到了,用 flock 來做
麻煩到讓我想。。運氣不會那麼糟吧,不要做這些事 XDDDD
→
01/26 16:37,
1年前
, 2F
01/26 16:37, 2F
沒看懂,什麼是 PV?
→
01/26 18:06,
1年前
, 3F
01/26 18:06, 3F
其實很早前我就覺得 mysql 可以用,只是它放硬碟,速度慢
而且我要自己建一個 table,裡面是 name 對應 value
還要自己編碼給各種資料型態
(value 用 text 就好,不管什麼 binary 都有法子編入 text
其實是很久前的工作,土法練鋼,和主管玩過一次)
但有 redis 就蠻像在做這些事,只是別人做好了,不用自己打造輪子
我的負擔是輕量化的,常是傳送 int, float, 頂多一些 string
image 是故意壓力測試的,其實我還想不到我有這需求
所以 redis 就夠了
目前用 MQTT 也夠了,就自己打造
方法是向 server 訂閱後,server 只要更新,我都抓下來 local 存而不用
等要用時再去存放處拿資料
雖然多了些 code, 但是不會有資料被洗掉剛好拿到空資料這種事
(有這概念,就算用 socket 自己從頭打造,也大概是這種樣子)
EPICS 先別說學不學得會了,它專長在哪,為何要用它,我都比較不出來 XD
粒子加速器?望遠鏡? 用這種方法描述似乎不能讓我看到重點
還是說'望遠鏡需要傳大畫面,所以這是能傳大檔,且符合我前面描述需求'的東西
那這樣我算有聽懂一些了
因為我的負擔不大,所以。。那應該就是 redis 就好
然後 PV 是什麼?
※ 編輯: HuangJC (49.217.130.232 臺灣), 01/26/2023 19:17:48
→
01/26 19:48,
1年前
, 4F
01/26 19:48, 4F
喔。。我的溫度就是
說到 call back,我有的用得到
比如何時遠端按鍵被按,或者脈衝式流量計
不過脈衝式流量計我會傾向於在 sensor.py 裡,就把它從脈衝變成數值
(有點像 DA 轉換,但多了積分)
傳出來的數值已經是類比型式,所以仍然可以讓遠端的 relay.py 去 polling
而不是需要被 call back
因此我大概都用不到 call back.
※ 編輯: HuangJC (49.217.130.232 臺灣), 01/26/2023 20:37:55
推
01/27 21:48,
1年前
, 5F
01/27 21:48, 5F
推
01/28 04:50,
1年前
, 6F
01/28 04:50, 6F
→
01/28 04:50,
1年前
, 7F
01/28 04:50, 7F
謝謝,我的確想過用 share memory 做
那麼這和 redis 的差別是什麼?要理解成競爭軟體嗎?
畢竟一個東西從來不限制只有一家公司能做
競爭的話,就是看誰便宜,看誰效能好的差別了
(我當然知道指令長得不一樣,但在決策上我還是會覺得兩者很像)
https://stackoverflow.com/questions/19477821/redis-cache-vs-using-memory-directly
https://tinyurl.com/6edh5emu
還真有人問
似乎是說,redis 可以存入硬碟,可以在下次執行時續用(因為它就是資料庫)
資料庫的話,跨語言也不成問題(比如 python 寫入,c 讀取)
當然 redis 也輕鬆跨電腦,畢竟它基於網路
但也因為基於網路,所以比純 memory 略慢
因此如果我的 sensor.py 和 relay.py 在同一台電腦,就用 share memory
要跨電腦,就用 redis...
-----
小惡魔的心聲:老闆才給多少錢,我才不要寫兩套
用 redis 就對了,不管在同一台電腦或跨電腦都能用 XD
※ 編輯: HuangJC (49.216.44.32 臺灣), 01/28/2023 18:58:28
→
01/30 01:40,
1年前
, 8F
01/30 01:40, 8F
→
01/30 01:40,
1年前
, 9F
01/30 01:40, 9F
→
01/30 01:41,
1年前
, 10F
01/30 01:41, 10F
→
01/30 01:41,
1年前
, 11F
01/30 01:41, 11F
→
01/30 01:41,
1年前
, 12F
01/30 01:41, 12F
→
01/30 01:41,
1年前
, 13F
01/30 01:41, 13F
→
01/30 01:42,
1年前
, 14F
01/30 01:42, 14F
→
01/30 01:42,
1年前
, 15F
01/30 01:42, 15F
→
01/30 01:42,
1年前
, 16F
01/30 01:42, 16F
→
01/30 01:45,
1年前
, 17F
01/30 01:45, 17F
→
01/30 10:05,
1年前
, 18F
01/30 10:05, 18F
感謝
ZMQ 似乎能讓我不用再從 TCP/IP 手工打造 message loop
D-BUS 看不懂
> D-Bus是一個行程間通訊及遠端程序呼叫機制,可以讓多個不同的電腦程式(即行程)
> 在同一臺電腦上同時進行通訊
既然它說遠端(RPC),那怎麼不說它也能跨電腦?
遠端呼叫經常是慢的,要寫成非同步,最後我的腦袋會變成自己思考 message loop
這樣我會有決策困難 XDDDD
※ 編輯: HuangJC (49.216.44.32 臺灣), 01/31/2023 07:01:22
→
01/31 11:23,
1年前
, 19F
01/31 11:23, 19F
如果它能跨電腦呢?那我就想去修 wiki 了
前不久在討論 RPI 晶片時,有位網友帶著我讀資料
他一邊翻 wiki 給我,一邊回憶他一路追這些晶片的沿革
然後很順口的說:所以 wiki 上寫錯了
XDDD 熱心的人很多,但錯誤也不少啦,但我們不敢馬上改下去
改東西不好輕舉妄動..
→
01/31 13:26,
1年前
, 20F
01/31 13:26, 20F
→
01/31 13:26,
1年前
, 21F
01/31 13:26, 21F
https://tinyurl.com/mtu3pvbc
有人做了這個比較
我想,dbus 能做的事太多了,對我的需求是殺雞用牛刀
所以我才看不懂。
(其實 zmq 我也是一行都沒用過,算不上會;但我就是能看懂一些特徵
會覺得我如果要用它,就能學會,會很好用)
就像在實作 message queue 前我只是像 mqtt 一樣丟資料,收資料
但有時發送端會一口氣丟一堆,接收端收一個,做一件事,才回報一件事做好了
因此才產生 message queue 的需求
懂了需求才會懂為何要有 queue,不然一開始我也不想做出 queue
※ 編輯: HuangJC (49.217.70.24 臺灣), 01/31/2023 18:34:01
討論串 (同標題文章)
完整討論串 (本文為第 3 之 3 篇):
8
21
Python 近期熱門文章
PTT數位生活區 即時熱門文章