我有2 threading.Thread
个,每个人都打电话:
p = subprocess.Popen(...)
o,e = p.communicate()
调用GIL
时似乎没有释放p.communicate()
。在上面的代码中,线程变为流水线,只有当第一个线程完成时,第二个线程才能启动,这不是所需的行为。
有没有办法以释放Popen
的方式等待GIL
?
答案 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
第一个线程已经与其进程通信后,第二个线程成功启动并进行通信。