日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

python子进程关闭fd_如果创建了multiprocessing.Pool,Python子进程wait()将失败

發布時間:2024/10/14 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python子进程关闭fd_如果创建了multiprocessing.Pool,Python子进程wait()将失败 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在一個使用subprocess到gzip輸出的簡單腳本中(使用subprocess.PIPE到外部命令的stdin),如果在創建子進程和關閉進程的stdin之間創建了multiprocessing.Pool對象,則subprocess.wait ()將永遠掛起.

import multiprocessing

import subprocess

proc = subprocess.Popen(["gzip", "-c", "-"],

stdout=open('filename', 'w'), stdin=subprocess.PIPE)

multiprocessing.Pool()

proc.stdin.close()

proc.wait()

移動multiprocessing.Pool調用一行或一行調用可以防止出現問題.

我在Python 2.7.3(Linux)和Python 2.7.1(OS X)上遇到過這種情況.

顯然,這是一個微不足道的例子 – 真正的用法要復雜得多.我也已經知道GzipFile了 – 我寧愿不使用它;使用子進程可以通過將gzipping分成單獨的線程來獲得更多的CPU使用率.

我看不出簡單地實例化Pool應該如何產生這種影響.

最佳答案 當您調用multiprocessing.Pool時,多處理模塊會創建幾個新進程(使用os.fork或類似的進程).

默認情況下,在fork期間,新進程會繼承所有打開的文件描述符.

當您使用subprocess.PIPE參數調用subprocess.Popen時,子流程模塊會創建一些新的管道文件描述符,以便向/從新進程發送數據.在這種特殊情況下,管道用于將數據從父進程(python)發送到子進程(gzip),并且gzip將退出 – 從而使proc.wait()完成 – 當對管道的所有寫訪問權限進行時遠. (這是在管道上生成“EOF”的原因:該管道不再存在可寫入的文件描述符.)

因此,在這種情況下,如果您(所有在“原始”python進程中)按此順序執行此操作:

>創建一個管道

>創建一些multiprocessing.Pool流程

>將數據發送到gzip

>關閉管道以gzip

然后,由于fork的行為,每個Pool進程都有一個寫入gzip管道的os.dup,因此gzip繼續等待更多數據,這些池進程可以(但從不這樣做)發送.一旦Pool進程關閉其管道描述符,gzip進程就會退出.

將其修復為真實(更復雜)的代碼可能非常重要.理想情況下,您希望多處理.Pool(知道,不知何故)應該保留哪些文件描述符,哪些不應該保留,但這并不像“只是在創建的子進程中關閉一堆描述符”那么簡單:

output = open('somefile', 'a')

def somefunc(arg):

... do some computation, etc ...

output.write(result)

pool = multiprocessing.Pool()

pool.map(somefunc, iterable)

顯然,output.fileno()必須由工作進程共享.

您可以嘗試使用Pool的初始化程序來調用proc.stdin.close(或在fd列表中的os.close),但是您需要安排跟蹤描述符到關閉.重構代碼可能最簡單,以避免“在錯誤的時間”創建池.

總結

以上是生活随笔為你收集整理的python子进程关闭fd_如果创建了multiprocessing.Pool,Python子进程wait()将失败的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。