亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

請問Popen等待子進程,即使直接子進程已終止

請問Popen等待子進程,即使直接子進程已終止

慕絲7291255 2019-11-03 11:04:20
我正在Windows 8 / XP上使用Python 2.7。我有一個程序A,它使用以下代碼運行另一個程序B:p = Popen(["B"], stdout=PIPE, stderr=PIPE)stdout, stderr = p.communicate()returnB運行批處理腳本C。C是運行時間較長的腳本,即使C尚未完成,我也希望B退出。我使用以下代碼(在B中)完成了此操作:p = Popen(["C"])return當我運行B時,它可以按預期工作。但是,當我運行A時,我希望它在B退出時退出。但是,即使B已經退出,A也會等到C退出。關于正在發生的事情以及可能的解決方案的任何想法?不幸的是,將A更改為B的明顯解決方案不是一種選擇。這是說明此問題的實用示例代碼:https : //www.dropbox.com/s/cbplwjpmydogvu2/popen.zip?dl=1非常感謝任何輸入。
查看完整描述

3 回答

?
慕容708150

TA貢獻1831條經驗 獲得超4個贊

您可以為子流程提供start_new_session模擬C:


#!/usr/bin/env python

import os

import sys

import platform

from subprocess import Popen, PIPE


# set system/version dependent "start_new_session" analogs

kwargs = {}

if platform.system() == 'Windows':

    # from msdn [1]

    CREATE_NEW_PROCESS_GROUP = 0x00000200  # note: could get it from subprocess

    DETACHED_PROCESS = 0x00000008          # 0x8 | 0x200 == 0x208

    kwargs.update(creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)  

elif sys.version_info < (3, 2):  # assume posix

    kwargs.update(preexec_fn=os.setsid)

else:  # Python 3.2+ and Unix

    kwargs.update(start_new_session=True)


p = Popen(["C"], stdin=PIPE, stdout=PIPE, stderr=PIPE, **kwargs)

assert not p.poll()



查看完整回答
反對 回復 2019-11-04
?
皈依舞

TA貢獻1851條經驗 獲得超3個贊

以下是根據塞巴斯蒂安的答案和此答案改編而成的代碼段:


#!/usr/bin/env python

import os

import sys

import platform

from subprocess import Popen, PIPE


# set system/version dependent "start_new_session" analogs

kwargs = {}

if platform.system() == 'Windows':

    # from msdn [1]

    CREATE_NEW_PROCESS_GROUP = 0x00000200  # note: could get it from subprocess

    DETACHED_PROCESS = 0x00000008          # 0x8 | 0x200 == 0x208

    kwargs.update(creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP, close_fds=True)  

elif sys.version_info < (3, 2):  # assume posix

    kwargs.update(preexec_fn=os.setsid)

else:  # Python 3.2+ and Unix

    kwargs.update(start_new_session=True)


p = Popen(["C"], stdin=PIPE, stdout=PIPE, stderr=PIPE, **kwargs)

assert not p.poll()

我只是在Windows上親自測試過。



查看完整回答
反對 回復 2019-11-04
?
慕的地10843

TA貢獻1785條經驗 獲得超8個贊

代碼的意圖是,std*=DEVNULL即,您不能在此處省略stdin / stdout / stderr(至少在POSIX上- close_fds=True不會在此處關閉std *)。close_fds=True除非您打開了其他(非標準)文件描述符(關閉它們或通過close_fds=True-POSIX上的Python 3的默認值),否則您不需要。在Windows上close_fds=True就足夠了(無需重定向),這樣子進程就不會繼承父進程的文件描述符(在這種情況下,如果您寫入stdout或在Windows上一起傳遞std*=DEVNULL  我還沒有測試過會發生什么close_fds=True)。


查看完整回答
反對 回復 2019-11-04
  • 3 回答
  • 0 關注
  • 394 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號