博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

实时获取管道信息的一个小框架

Posted on 2017-02-06 00:40  SolHe  阅读(420)  评论(0编辑  收藏  举报

今天花了点时间了解了管道的相关知识,学会了实时获取管道信息的方式,通过这种方式,我可以很简单的将subprocess.Popen()中的标准输出实时获取到,进而利用这些实时信息实现更灵活更强大的功能。

废话不多说,代码如下:

 

import subprocess
import threading
import time
string = '"/Applications/Nuke10.0v4/NukeX10.0v4.app/../Nuke10.0v4.app/Contents/MacOS/Nuke10.0v4" -t -F 1-100 -m 4 -x /Users/SolHe/Downloads/test.nk'
f = subprocess.Popen(string, shell=True, stdout=subprocess.PIPE)
def check():
    oldcontent = ""
    while 1:
        f.stdout.flush()
        newcontent = f.stdout.readline()
        if oldcontent != newcontent:
            print newcontent
            oldcontent = newcontent
        if f.poll() == 0:
            print "finish"
            break
    return

g = threading.Thread(target=check)
g.start()
g.join()

 

首先建立一个子进程f,该进程执行外部程序,启动nuke的渲染;再建立一个线程g,该线程执行check()函数来实时获取f进程的标准输出,而获取实时输出的关键在于f.stdout.flush(),只有每次首先利用flush清空标准输出的缓存空间,才能获取到实时的信息。如果不做清空,那么stdout是有缓存结束才会返回管道信息,这样就不实时了。所以在这里想要实时,就必须手动清空缓存。

 

 

在这里再附上一个关于多进程库multyprocessing的小案例mark一下:

from multiprocessing import Process, Pipe

def send(pipe):
    "send"
    pipe.send(['spam'] + [42, 'egg'])
    pipe.close()

def talk(pipe):
    "talk"
    pipe.send(dict(name='Bob', spam=42))
    reply = pipe.recv()
    print('talker got:', reply)

if __name__ == '__main__':
    con1, con2 = Pipe()
    sender = Process(target=send, name='send', args=(con1,))
    sender.start()
    print "con2 got: %s" % con2.recv()#从send收到消息
    con2.close()
    (parentEnd, childEnd) = Pipe()
    child = Process(target = talk, name = 'talk', args = (childEnd,))
    child.start()
    print('parent got:', parentEnd.recv())
    parentEnd.send({x * 2 for x in 'spam'})
    child.join()
    print('parent exit')

这个案例就不做过度解释了,非常简单,利用了管道这种特性实现了信息交互,以后写高并发程序的时候非常有用。

关于管道和进程的知识还得多学习,以上。