2014-01-29 36 views
0

如何啓動IPC與子進程,而不讓它繼承所有句柄?爲了使它更有趣,這個窗口以及unix工作。如何在不泄漏手柄(跨平臺)的情況下做本地IPC?

背景:我寫了3rparty共享庫接口庫(我們叫它IT)又包含全球數據(即真應的對象!)。我想要有這個全局數據的多個實例。據我瞭解,我有兩個選擇,以解決這個問題:

  1. 創建,對IT的靜態變形鏈接用Cython模塊,然後複製並導入模塊,每當我想要一個新的實例。類似地,我可以複製IT,但是創建ctypes界面的工作量更大。

  2. 產卵加載它,並與其建立IPC連接的子進程。

有使用(2)有幾個原因:

  • 我不知道,如果(1)以任何方式可靠,感覺像一個壞主意(用時會發生什麼所有額外的模塊,當應用程序以不受控制的方式退出?)。爲了安全考慮,將IT裝箱成單獨的流程可能實際上是一個好主意:IT處理潛在的不安全輸入和IT代碼質量不是太好。所以,我寧願在運行時沒有打開任何安全資源。

  • 有可能是需要大量的這類IPC在未來的應用

所以我有哪些選擇?我已經看過成:

  • multiprocessing.Process起初看起來不錯,直到我意識到,新工藝得到我的所有句柄的副本。不用說,這是很有問題的,因爲現在通過在父進程中關閉它們以及前面提到的安全問題,無法可靠地釋放資源。

  • 使用os.closerange一個multiprocessing.Process內關閉所有的人工處理 - 除了管我很感興趣,請問os.closerange結束時只有文件或者它照顧其他類型的資源,以及?如果是這樣的話:給定Pipe對象,如何確定範圍?

  • 在UNIX上subprocess.Popen(.., close_fds=True, stdin=PIPE, stdout=PIPE)工作正常,但無法在Win32。

  • 命名管道都在Win32和UNIX非常不同。他們的任何圖書館都是他們的用法?

  • 套接字。有前途,特別是因爲它們是可以與套接字配合使用的方便的RPC庫。另一方面,我擔心這可能會導致大量的安全問題。我已經確定是來自當地的套接字(sock.getpeername()[0] == '127.0.0.1')可以防止回火?

有沒有可能忽略我?

總結:主要問題是如何在windows + unix上建立一個帶子進程的安全IPC?但是,如果你只知道部分問題的答案,請不要猶豫。

感謝您花時間閱讀它!

回答

0

看來python> = 3.4 subprocess.Popen(..., stdin=PIPE, stdout=PIPE, close_fds=False)是一個可能的選項。這是由於所有打開的文件描述符默認情況下都是非可繼承的。更確切地說,它們將在execv(因此仍不能使用multiprocessing.Process)自動關閉,請參閱PEP 446

這也適用於其他Python版本的有效選項:

  • 在Windows上,手柄是創建的非繼承默認情況下,所以你會泄漏只有那些對POSIX取得可繼承明確
  • 手柄/蟒蛇< = 3.3,你仍然可以使用os.closerange產卵子

了相應的例子看後關閉打開的文件描述符:

https://github.com/coldfix/python-ipc-test

最有用的組合是:

  1. 標準輸入輸出:泡菜

    • 親:完全跨平臺,在我的測試中
    • 親:最快的選項(與2)
    • CON:標準輸入/輸出不能獨立重定向
  2. inherit_unidir:泡菜

    • 親:可以重定向STDIO獨立流
    • 專業用戶:使用標準輸入輸出一起最快的選擇:pickle
    • con:非常低層次的平臺特定c頌
  3. 插座:sockpipe

    • 親:跨平臺毫不費力
    • CON:有當 「黑客」 可以連接到端口短期內,你可能需要一個密碼短語或其他東西來防止這種情況的發生
    • con:比windows上的選擇稍微慢一些(因子1。6在我的測量)
    • 不使用AF_UNIX當有不可預知的性能影響在Linux上
相關問題