为什么使用Popen的线程python代码在Windows和Linux上表现不同

时间:2014-06-06 14:12:06

标签: python linux windows multithreading popen

我有以下python代码,它在Linux上运行良好,但永远等待Windows上的反馈。我在Linux上运行Python 2.6.6,在Windows上运行python 2.7.2,并且正在使用Cygwin-x86_64中的tee程序。如果问题在其他人的Windows构建中似乎不可重现,我可以提供有关我的设置的更多详细信息。这是脚本:

from __future__ import with_statement

# from http://stackoverflow.com/questions/375427/non-blocking-read-on-a-subprocess-pipe-in-python

import sys
from subprocess import PIPE, STDOUT
import subprocess, time
from threading  import Thread
import os, subprocess
import re, time
from Queue import Queue, Empty

ON_POSIX = 'posix' in sys.builtin_module_names

def enqueue_output(out, queue):
    for line in iter((lambda : out.read(1)), b''):
        # print('0: %s' % line)
        queue.put(line)
    out.close()

class Popen_async(object):
    """Allows non-blocking reading from a Popen, by

    p = Popen_async(['myprogram.exe'], stdout=PIPE, stderr=PIPE)
    try:  line = p.stdout.get_nowait() # or p.stdout.get(timeout=.1)
    except Empty:
        print('no output yet')
    else: # got line
    """
    def __init__(self, *args, **kwargs):
        self._p = subprocess.Popen(*args, bufsize=1, close_fds=ON_POSIX, **kwargs)
        self.stdout = Queue()
        self.stderr = Queue()
        self._tout = Thread(target=enqueue_output, args=(self._p.stdout, self.stdout))
        # self._terr = Thread(target=enqueue_output, args=(self._p.stderr, self.stderr))
        self._tout.daemon = True # thread dies with the program
        # self._terr.daemon = True # thread dies with the program
        self._tout.start()
        # self._terr.start()
        self.stdin = self._p.stdin
        time.sleep(0.1)

def get_all_nowait_iter(q):
    try:
        while True:
            yield q.get_nowait()
    except Empty:
        pass

def get_all_nowait(q):
    return ''.join(get_all_nowait_iter(q))

def get_all_semiwait_iter(q):
    def log_and_return(val):
        print(val)
        return val
    try:
        # this is blocking; TODO(jgross): Figure out how to get coqtop
        # to tell us if it's finished computing
        yield log_and_return(q.get(True))
        while True:
            yield log_and_return(q.get(True, 0.1))
    except Empty:
        pass

def get_all_semiwait(q):
    return ''.join(get_all_semiwait_iter(q))

def run(filename='log'):
    p = Popen_async(['tee', filename], stdout=PIPE, stderr=STDOUT, stdin=PIPE)
    time.sleep(1)
    for i in range(10):
        print('Write: %s' % (str(i) + '\n'))
        p.stdin.write(str(i) + '\n')
        print('Wait to read...')
        stdout = get_all_semiwait(p.stdout)
        print('Read: %s' % stdout)

if __name__ == '__main__':
    run()

Windows和Linux之间行为差异的原因是什么?

0 个答案:

没有答案