日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

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

發布時間:2024/10/14 python 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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()将失败的全部內容,希望文章能夠幫你解決所遇到的問題。

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