1 回答

TA貢獻(xiàn)2011條經(jīng)驗(yàn) 獲得超2個(gè)贊
盡管我相信您最好使用偵聽端口的服務(wù)器 - 客戶端類型的解決方案,但您要問的是 100% 可能使用signal
和os
庫。這種方法不適用于多線程程序,但是因?yàn)樾盘?hào)僅由 python 中的父線程處理。此外,windows 不會(huì)以相同的方式實(shí)現(xiàn)信號(hào),因此選項(xiàng)更加有限。
信號(hào)
“客戶端”進(jìn)程可以使用os.kill(pid, signal)
. 您必須查看可用信號(hào)并確定要使用哪個(gè)信號(hào)(signal.NSIG
可能是一個(gè)不錯(cuò)的選擇,因?yàn)樗粦?yīng)該影響任何其他默認(rèn)行為)。
啟動(dòng)時(shí)的“守護(hù)進(jìn)程”進(jìn)程必須注冊(cè)一個(gè)處理程序,以便在它接收到您選擇的信號(hào)時(shí)執(zhí)行什么操作。處理程序是一個(gè)您必須定義的函數(shù),它接收接收到的信號(hào)本身以及 executon ( def handler(signum, frame):
)的當(dāng)前堆棧幀。如果你只用這個(gè)處理程序做一件事,并且它不需要知道它被調(diào)用時(shí)發(fā)生了什么,你可以忽略這兩個(gè)參數(shù)。然后您必須使用signal.signal
ex:注冊(cè)處理程序signal.signal(signal.NSIG, handler)
。
從那里你會(huì)想找到一些合適的方法來等待下一個(gè)信號(hào)而不消耗太多資源。這可以像循環(huán)os.sleep
命令一樣簡(jiǎn)單,或者您可以嘗試變得花哨。我不確定 100% 從信號(hào)處理程序返回時(shí)如何恢復(fù)執(zhí)行,因此您可能需要關(guān)注遞歸深度(即,確保每次處理信號(hào)時(shí)都不要遞歸,否則您將永遠(yuǎn)能夠在需要重新啟動(dòng)之前處理有限數(shù)量的信號(hào))。
服務(wù)器
讓進(jìn)程監(jiān)聽端口(通常稱為服務(wù)器,但在功能上與您的“守護(hù)進(jìn)程”描述相同)而不是監(jiān)聽操作系統(tǒng)信號(hào)有幾個(gè)主要優(yōu)點(diǎn)。
端口能夠在信號(hào)只能觸發(fā)事件的地方發(fā)送數(shù)據(jù)
端口更相似跨平臺(tái)
端口在多線程中玩得很好[r]
端口使通過網(wǎng)絡(luò)發(fā)送消息變得容易(即:從手機(jī)創(chuàng)建提醒并在 PC 上執(zhí)行)
一次等待多件事
為了解決同時(shí)等待多個(gè)進(jìn)程的需要(偵聽輸入以及等待發(fā)送下一個(gè)通知),您有很多選擇:
信號(hào)實(shí)際上可能是一個(gè)很好的用例,因?yàn)?code>signal.SIGALRM它可以用作方便地重新設(shè)置的鬧鐘(如果您使用的是 UNIX)。您可以像以前一樣設(shè)置處理程序,只需為下一個(gè)通知設(shè)置警報(bào)。設(shè)置警報(bào)后,您可以簡(jiǎn)單地繼續(xù)在端口上偵聽新任務(wù)。如果有新任務(wù)進(jìn)入,再次設(shè)置警報(bào)將覆蓋現(xiàn)有任務(wù),因此處理程序需要檢索下一個(gè)排隊(duì)通知并在第一個(gè)任務(wù)完成后重新設(shè)置警報(bào)。
線程既可以用于輪詢通知任務(wù)隊(duì)列,也可以創(chuàng)建一個(gè)單獨(dú)的線程來等待每個(gè)任務(wù)。這不是一個(gè)特別優(yōu)雅的解決方案,但它會(huì)有效且易于實(shí)施。
最優(yōu)雅的解決方案可能是使用
asyncio
協(xié)程,但是我對(duì) asyncio 不太精通,并且承認(rèn)它們比線程更令人困惑。
添加回答
舉報(bào)