如何在subprocess.Popen.communicate()中发布GIL

时间:2016-02-26 00:09:42

标签: python python-2.7

我有2 threading.Thread个,每个人都打电话:

p = subprocess.Popen(...)
o,e = p.communicate()

调用GIL时似乎没有释放p.communicate()。在上面的代码中,线程变为流水线,只有当第一个线程完成时,第二个线程才能启动,这不是所需的行为。

有没有办法以释放Popen的方式等待GIL

2 个答案:

答案 0 :(得分:1)

使用multiprocessing模块而不是threading

查看https://docs.python.org/2/library/multiprocessing.html简介中的第一句话。

或者,如果您仍想使用线程,请不要调用communicate(),而是使用stdin和stdout管道。你仍然要小心,因为你可能会无意中锁定一个进程。例如,如果您在没有可用数据时尝试从进程的stdout读取,则会发生这种情况。您必须确切知道数据何时可用,以及可用的字节数(这不完全是轮询)。

p = subprocess.Popen( ..., stdin=subprocess.PIPE, stdout=subprocess.PIPE )
p.stdin.write( ... )
n = 1
x = p.stdout.read(n)  # this will lock if less than N bytes are available          

答案 1 :(得分:0)

似乎正在发生其他事情。您描述的阻止行为不是我在以下脚本中看到的:

start.py

import threading
import subprocess
import time


def run_script():
    print "Thread started"
    p = subprocess.Popen(
        ['./script.sh'],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
    )
    print "Communicating"
    out, err = p.communicate()
    print out, err


thread1 = threading.Thread(target=run_script)
thread1.start()

time.sleep(1)

thread2 = threading.Thread(target=run_script)
thread2.start()

script.sh

#!/bin/bash

for i in {1..5}
do
   echo "Welcome $i times"
   sleep 0.5
done

输出

> python start.py
Thread started
Communicating
Thread started
Communicating
Welcome 1 times
Welcome 2 times
Welcome 3 times
Welcome 4 times
Welcome 5 times

Welcome 1 times
Welcome 2 times
Welcome 3 times
Welcome 4 times
Welcome 5 times

第一个线程已经与其进程通信后,第二个线程成功启动并进行通信。