2010-06-10 49 views
3

我想解決以下問題:假設我有一個使用C++擴展模塊(通過SWIG創建的)的Python腳本(我們稱之爲Test.py)調用模塊「示例」)。我在同一個目錄下有Test.py,Example.py和_Example.so。正在執行Python腳本時替換Python擴展模塊的問題

現在,在運行Test.py的過程中,我想對我的示例模塊進行更改,重新編譯(將覆蓋現有的.so),並使用命令正常停止Test.py,使用舊版本的模塊(Test.py有一些清理工作,它使用一些在示例模塊中定義的內容),然後使用新版本的模塊重新啓動它。在我的情況下,優雅地停止Test.py和THEN重新編譯模塊不是一種選擇。

問題是,只要_Example.so被覆蓋並且Test.py嘗試訪問示例模塊中定義的任何東西(正常停止時),就會出現分段錯誤。對此的一個解決方案是通過在最後附加版本號來明確指定示例模塊,但我想知道是否有更好的解決方案(我不想導入Example_1_0)?

回答

2

你可以,就開始Test.py,文件複製爲例。*獨特該實例的臨時文件夾(看看tempfile.mkdtemp,它可以創建安全,獨特的文件夾),添加到sys.path然後導入例子;並在Test.py關閉刪除該文件夾(shutils.rmtree)在清理階段。

這意味着Test.py的每個實例都將在其自己的Example模塊副本上運行,而不會干擾其他實例,並且只有在重新啓動時纔會更新爲新的實例。

您需要將Example。*文件放在與Test.py相同的文件夾中,否則導入將首先得到這些文件。只要將它們存儲在子文件夾中應該沒問題。

+0

哈克解決方案 - 我喜歡它!它效果很好,謝謝你的幫助! – dogman 2010-06-10 22:08:16

+1

我喜歡你的解決方案比我的更好。 (OT)大家都喜歡*拒絕* ... – 2010-06-11 13:05:00

0

您可以編譯爲臨時名稱(Example_1_0),但只要Test.py停止,請重命名爲_Example.so和,然後重新啓動Test.py。


編輯:

因爲你運行多個實例,您可以考慮使用某種類型的棧/發電機/符號鏈接線程給它的所有鏈接在一起就做自己的「垃圾收集」 _Example.so:

您可以運行主測試腳本,啓動帶有子進程的Test.py腳本。每個Test.py都可以將_ExampleXXX.so作爲命令行參數。然後,對每個.so文件保留一個引用計數 - 當引用計數下降到零時,該模塊的版本將被刪除,並且該進程將使用最新版本的_Example.so重新生成。

這可能是一個有點棘手,但你可能只是能夠使用

while True: 
    #Do stuff 
    for p in myprocesses: 
     retcode = p.poll() # Set to [None][1] if the process hasn't finished 
     # Do something with the return code 

或一些類似的邏輯。

+0

感謝您的回覆。不幸的是,這不是一個選項,因爲我有多個Test.py實例運行,並且由於各種原因,我需要以串行方式重新啓動所有實例(我無法立即停止所有實例)。 – dogman 2010-06-10 20:19:39