2013-01-23 20 views
0

基本上这个代码从管道读取并不断打印输出而不会阻塞...这里是整个代码:呼叫脚本而不阻断解释需要

1)第一脚本:

if __name__ == '__main__': 
    for i in range(5): 
     print str(i)+'\n', 
     sys.stdout.flush() 
     time.sleep(1) 

2)第二个脚本:

def log_worker(stdout): 

    while True: 
     output = non_block_read(stdout).strip() 
     if output: 
      print output 


def non_block_read(output): 
    ''' even in a thread, a normal read with block until the buffer is full ''' 
    fd = output.fileno() 
    fl = fcntl.fcntl(fd, fcntl.F_GETFL) 
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) 
    try: 
     return output.read() 
    except: 
     return '' 

if __name__ == '__main__': 

    mysql_process = subprocess.Popen(['python','-u', 'flush.py'], stdin=sys.stdin, 
     stdout=subprocess.PIPE, 
     stderr=subprocess.PIPE) 


    thread = Thread(target=log_worker, args=[mysql_process.stdout]) 
    thread.daemon = True 
    thread.start() 

    mysql_process.wait() 
    thread.join(timeout=1) 

我想知道为什么它的工作原理是这样:

1)如果我把Thread全部拿走,并且在main中调用log_worker也会一一打印所有内容,但问题是它在完成后会挂起而没有完成。而且我在某处读到这里的线程完全用于完成或更正确的线程死亡时,它完成打印的东西,那么它为什么这样工作?在这里以及如何做什么线程?

2)如果我保持线程,但删除mysql_process.wait()和thread.join它不打印....为什么?我读过Popen.wait是为了它的子进程终止。设置并返回returncode属性。这里的孩子过程是什么,为什么/如何是孩子O_O?

3)如果我只删除thread.join(timeout = 1),那么它完成但错误Exception in thread Thread-1 (most likely raised during interpreter shutdown):。为什么?在这里扮演什么角色。

4)我读了non_block_read函数中使用的函数的文档,但仍然很困惑。好吧,很明显,他们采取文件描述符并将其设置为非阻塞。我感到困惑的是,我可以使用所有这些函数,我的意思是我明白文件上,但他们如何使用它在标准输出O_O?这不是一个文件,它是一个流~~?

我所做的这一切都是通过subprocess.Popen在龙卷风脚本中执行脚本,并不断发送输出给客户端/我自己而不会阻塞,所以如果任何人都可以帮助我这么做,我会非常感激,因为我可以“难以想象如何样得到线程这个输出的方式,我可以constanly插入它在tornadio2 self.send ...

def on_message(self, message): 
#  list = subprocess.Popen([r"ls", "-l"], stdout=subprocess.PIPE) 
#  list_stdout = list.communicate()[0] 
     for i in range(1,10): 
      time.sleep(1) 
      self.send(i) 

回答

0

随着开发的版本(3.2),这是真的容易

from tornado.web import RequestHandler,asynchronous 
from tornado.process import Subprocess 

class home(RequestHandler): 
    @asynchrounous 
    def get(self): 
    seld.sp=Subprocess('date && sleep 5 && date',shell=True,stdout=Subprocess.STREAM) 
    self.sp.set_exit_callback(self.next) 
    def next(self,s): 
    self.sp.stdout.read_until_close(self.finish) 

application = ...