Python處理序間通訊之匿名管道

來源:互聯網
上載者:User

標籤:python   管道   通訊   

匿名管道

管道是一個單向通道,有點類似共用記憶體緩衝.管道有兩端,包括輸入端和輸出端.對於一個進程的而言,它只能看到管道一端,即要麼是輸入端要麼是輸出端.

os.pipe()返回2個檔案描述符(r, w),表示可讀的和可寫的.範例程式碼如下:

#!/usr/bin/pythonimport timeimport osdef child(wpipe):    print(‘hello from child‘, os.getpid())    while True:        msg = ‘how are you\n‘.encode()        os.write(wpipe, msg)        time.sleep(1)def parent():    rpipe, wpipe = os.pipe()    pid = os.fork()    if pid == 0:        child(wpipe)        assert False, ‘fork child process error!‘    else:        os.close(wpipe)        print(‘hello from parent‘, os.getpid(), pid)        fobj = os.fdopen(rpipe, ‘r‘)        while True:            recv = os.read(rpipe, 32)            print recvparent()

輸出如下:

(‘hello from parent‘, 5053, 5054)(‘hello from child‘, 5054)how are youhow are youhow are youhow are you

我們也可以改進代碼,不用os.read()從管道中讀取二進位位元組,而是從檔案對象中讀取字串.這時需要用到os.fdopen()把底層的檔案描述符(管道)封裝成檔案對象,然後再用檔案對象中的readline()方法讀取.這裡請注意檔案對象的readline()方法總是讀取有分行符號’\n’的一行,而且連分行符號也讀取出來.還有一點要改進的地方是,把父進程和子進程的管道中不用的一端關閉掉.

#!/usr/bin/pythonimport timeimport osdef child(wpipe):    print(‘hello from child‘, os.getpid())    while True:        msg = ‘how are you\n‘.encode()        os.write(wpipe, msg)        time.sleep(1)def parent():    rpipe, wpipe = os.pipe()    pid = os.fork()    if pid == 0:        os.close(rpipe)        child(wpipe)        assert False, ‘fork child process error!‘    else:        os.close(wpipe)        print(‘hello from parent‘, os.getpid(), pid)        fobj = os.fdopen(rpipe, ‘r‘)        while True:            recv = fobj.readline()[:-1]            print recvparent()

輸出如下:

(‘hello from parent‘, 5108, 5109)(‘hello from child‘, 5109)how are youhow are youhow are you

如果要與子進程進行雙向通訊,只有一個pipe管道是不夠的,需要2個pipe管道才行.以下樣本在父進程建立了2個管道,然後再fork子進程.os.dup2()實現輸出和輸入的重新導向.spawn功能類似於subprocess.Popen(),既能發送訊息給子進程,由能從子子進程擷取返回資料.
?

#!/usr/bin/python#coding=utf-8import os, sysdef spawn(prog, *args):    stdinFd = sys.stdin.fileno()    stdoutFd = sys.stdout.fileno()    parentStdin, childStdout = os.pipe()    childStdin, parentStdout= os.pipe()    pid = os.fork()    if pid:        os.close(childStdin)        os.close(childStdout)        os.dup2(parentStdin, stdinFd)#輸入資料流綁定到管道,將輸入重新導向到管道一端parentStdin        os.dup2(parentStdout, stdoutFd)#輸出資料流綁定到管道,發送到子進程childStdin    else:        os.close(parentStdin)        os.close(parentStdout)        os.dup2(childStdin, stdinFd)#輸入資料流綁定到管道        os.dup2(childStdout, stdoutFd)        args = (prog, ) + args        os.execvp(prog, args)        assert False, ‘execvp failed!‘if __name__ == ‘__main__‘:    mypid = os.getpid()    spawn(‘python‘, ‘pipetest.py‘, ‘spam‘)    print ‘Hello 1 from parent‘, mypid #列印到輸出資料流parentStdout, 經管道發送到子進程childStdin    sys.stdout.flush()    reply = raw_input()    sys.stderr.write(‘Parent got: "%s"\n‘ % reply)#stderr沒有綁定到管道上    print ‘Hello 2 from parent‘, mypid    sys.stdout.flush()    reply = sys.stdin.readline()#另外一種方式獲得子進程返回資訊    sys.stderr.write(‘Parent got: "%s"\n‘ % reply[:-1]) 

pipetest.py代碼如下:

#coding=utf-8import os, time, sysmypid = os.getpid()parentpid = os.getppid()sys.stderr.write(‘child %d of %d got arg: "%s"\n‘ %(mypid, parentpid, sys.argv[1]))for i in range(2):    time.sleep(3)    recv = raw_input()#從管道擷取資料,來源於父經常stdout    time.sleep(3)    send = ‘Child %d got: [%s]‘ % (mypid, recv)    print(send)#stdout綁定到管道上,發送到父進程stdin    sys.stdout.flush()

輸出:

child 7265 of 7264 got arg: "spam"Parent got: "Child 7265 got: [Hello 1 from parent 7264]"Parent got: "Child 7265 got: [Hello 2 from parent 7264]"

Python處理序間通訊之匿名管道

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.