Python程序間通訊之匿名管道

2021-09-02 10:28:04 字數 4132 閱讀 9643

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

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

#!/usr/bin/python

import time

import os

defchild

(wpipe):

print('hello from child', os.getpid())

while

true:

msg = 'how are you\n'.encode()

os.write(wpipe, msg)

time.sleep(1)

defparent

(): 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 recv

parent()

輸出如下:

('hello from parent', 5053, 5054)

('hello from child', 5054)

how are you

how are you

how are you

how are you

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

#!/usr/bin/python

import time

import os

defchild

(wpipe):

print('hello from child', os.getpid())

while

true:

msg = 'how are you\n'.encode()

os.write(wpipe, msg)

time.sleep(1)

defparent

(): 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 recv

parent()

輸出如下:

('hello from parent', 5108, 5109)

('hello from child', 5109)

how are you

how are you

how are you

如果要與子程序進行雙向通訊,只有乙個pipe管道是不夠的,需要2個pipe管道才行.以下示例在父程序新建了2個管道,然後再fork子程序.os.dup2()實現輸出和輸入的重定向.spawn功能類似於subprocess.popen(),既能傳送訊息給子程序,由能從子子程序獲取返回資料.

#!/usr/bin/python

#coding=utf-8

import os, sys

defspawn

(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-8

import os, time, sys

mypid = 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程序間通訊之匿名管道

管道是乙個單向通道,有點類似共享記憶體快取.管道有兩端,包括輸入端和輸出端.對於乙個程序的而言,它只能看到管道一端,即要麼是輸入端要麼是輸出端.os.pipe 返回2個檔案描述符 r,w 表示可讀的和可寫的.示例 如下 usr bin python import time import os def...

Ubuntu下Linux程序間通訊 匿名管道

linux程序間通訊 匿名管道 linux程序間通訊 fifo 有名管道 linux程序間通訊 訊息佇列 linux程序間通訊 訊號量 linux程序間通訊 共享記憶體 linux提供了多種程序間通訊的方法,常見有管道 匿名 fifo 有名管道 訊息佇列 訊號量 共享記憶體,socket通訊。1.匿...

Linux 程序間通訊之匿名管道

程序間通訊 目的 分類 管道 把乙個程序連線到另乙個程序的乙個資料流稱為管道 匿名管道 include 建立乙個無名管道 intpipe int pipefd 2 pipefd 檔案描述附陣列 pipefd 0 表示讀端,pipefd 1 表示寫端 成功返回0 失敗返回錯誤 呼叫pipe函式的程序 ...