用 C 來守護 Python 程序

2022-01-22 21:13:10 字數 3267 閱讀 7838

目前我主要負責的乙個專案是乙個c/s架構的客戶端開發,前端主要是通過wpf相關技術來實現,後端是通過python來實現,前後端的資料通訊則是通過mq的方式來進行處理。由於python程序是需要依賴客戶端程序來執行,為了保證後端業務程序的穩定性,就需要通過乙個守護程序來守護 python 程序,防止其由於未知原因而出現程序退出的情況。這裡簡單記錄一下我的一種實現方式。

對於我們的系統而言,我們的 python 程序只允許存在乙個,因此,對應的服務型別要採用單例模式,這一部分**相對簡單,就直接貼出來了,示例**如下所示:

public partial class pythonservice}}

return _instance;}}

private pythonservice()

}

由於後端的 python **執行需要安裝一些第三方的擴充套件庫,所以為了方便,我們採用的方式是總結將 python 安裝檔案及擴充套件包和他們的**一併打包到我們的專案目錄中,然後建立乙個 python 程序,在該程序中通過設定環境變數的方式來為 python 程序進行一些環境配置。示例**如下所示:

public partial class pythonservice

public void stop()

private int createprocess()

;psi.createnowindow = true;

var path = psi.environmentvariables["path"];

if (path != null)

).where(p => !p.tolower().contains("python")).tolist();

array.addrange(new );

psi.environmentvariables["path"] = string.join(";", array);

}var ps = new process ;

if (ps.start())

return pid;

}private static void killprocessandchildren(int pid)

managementobjectsearcher searcher = new managementobjectsearcher("select * from win32_process where parentprocessid=" + pid);

managementobjectcollection moc = searcher.get();

foreach (managementobject mo in moc)

trycatch (argumentexception)

catch (win32exception)}}

這裡有一點需要注意一下,建議使用pid來標識我們的 python 程序,因為如果你使用程序例項或其它方式來對當前執行的程序設定乙個引用,當該程序出現一些未知退出,這個時候你通過哪個引用來進行相關操作是會出問題的。

上面我們的通過記錄當前正在執行的程序的pid來標識我們的程序,那對應守護程序,我們就可以通過程序列表查詢的方式來進行建立,在輪詢的過程中,如果未找到對應 pid 的程序則表明該程序已經退出,需要重新建立該程序,否則就不執行任何操作,示例**如下所示:

public partial class pythonservice

-");

if (!has)

-");

}thread.sleep(2000);

}}, token);}}

這裡我使用的是thread.sleep(2000)方式來繼續執行緒等待,你也可以使用await task.delay(2000,token),但是使用這種方式在傳送取消請求時會產生乙個taskcanceledexception的異常。所以為了不產生不必要的異常資訊,我採用第一種解決方案。

接著,完善我們的startstop方法,示例**如下所示:

public void start()

var msg = isrunning ? "服務啟動成功..." : "服務啟動失敗...";

trace.writeline(msg);

}public void stop()

最後,上層呼叫就相對簡單一下,直接呼叫start方法和stop方法即可。

在我們的實際專案**中,pythonservice的**要比上面的**稍微複雜一些,我們內部還新增了乙個 mq 的 訊息佇列。所以為了演示方便,我這裡只列出了和本文相關的核心**,在具體的使用過程中,可以依據本文提供的一種實現方法來進行加工處理。

這裡我需要說明一下,我們的客戶端對應的後端服務是python寫的,並且指令碼數量巨多無比,每個指令碼之間又是相互獨立的模組,相關的依賴庫都不一樣,所以這就導致乙個問題,如果使pythonnetironpython這種整合框架,那麼每個模組需要使用到的依賴包就需要放到我們客戶端來維護管理安裝。從工程設計的角度來講,這個工作由我們客戶端組來做是不太合適的,雖然技術上是可行的,但是這無疑是乙個坑。

因為我們的python後端服務呼叫的很多第三方元件(部分是非自研)是多種型別的,後端服務無法保證能穩定呼叫每乙個第三方元件不崩潰,這就要求我們客戶端必須要做乙個守護程序來監測後端服務程序的狀態,當其崩潰後要能重新啟動。

我很能理解為什麼有很多朋友會有上面兩個疑惑,其實做技術的很多都會陷入乙個誤區:單純的考慮技術實現,而不關注業務解耦。這個怎麼說呢,有好處也有不好的地方,但是我個人覺得,如果只是關注技術,而不切入業務,最後即使每個技術細節實現的很完美,但是業務緊耦合,這個專案依舊難以可持續發展

用c 實現通用守護程序

2011 02 12 11 55 by 田志良,4523 visits,收藏,編輯 2.安裝注意事項 3.需求分析 使用者指定要守護的應用程式 數量不限 該應用程式不僅包括exe可執行檔案,還包括諸如jpg txt等所有能雙擊開啟執行的應用程式。使用者設定好要守護的應用程式後,關閉應用程式 包括合法...

用Python給Linux編寫守護程序

守護程序 daemon 是指在unix或其他多工作業系統中在後台執行的電腦程式,並不會接受電腦使用者的直接操控。此類程式會被以程序的形式初始化。通常,守護程序沒有任何存在的父程序 即ppid 1 且在unix系統程序層級中直接位於init之下。守護程序程式通常通過如下方法使自己成為守護程序 對乙個子...

python守護程序

去 python daemon 1.5.2 3.el5.noarch.rpm 測試 test.py usr bin python import daemon,time print 1 p daemon.daemoncontext p.open for i in range 0,100 print t...