【代码】multiprocessing Pipe和os FIFO

本文探讨了使用multiprocessing模块的Pipe与Process实现全双工通信,以及os模块的FIFO(有名管道)配合os.fork()进行半双工通信。FIFO通过mkfifo创建,允许父子进程间的单向通信,文中提到了一些实际操作中的现象和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

multiprocessing模块 pipe配合Process

这种是全双工的,当然这里设置为半双工

import time, os
from multiprocessing import Process, Pipe

pread, pwrite = Pipe(False)

def f():
    i = 0
    while i<10:
    	# 子进程每次等待,并从管道挤出一次消息,只要有就能取出来,读完了还recv,阻塞了。。。。
        time.sleep(1)
        data = pread.recv()
        print(os.getppid(), 'send', data,'to', os.getpid())
        i += 1


p = Process(target=f)
p.start()

i = 0
while i<5:
	# 主进程立即、一股脑儿塞到管道里,当然也可以time.sleep(1),一次放一个,这样发送和子进程接收似乎就能同步
    pwrite.send(str(i))
    print(os.getpid(), 'sent')
    i += 1

# 顯send,最後再join
p.join()



os模块 FIFO配合os.fork()

FIFO也被称为有名管道(named pipe),使用mkfifo函数可以创建,是半双工的,参考父进程和子进程拥有共同的读写文件描述符,可以实现子进程写文件,父进程读文件的操作。
这里仅仅是父子进程之间的FIFO,两个无关的进程没有测试
首先是,主进程发给子进程,这种情况的结果比较奇怪,但是父子进程之间互发消息功能都可以实现吧

#!/usr/bin/python3.6

import time, os

pipe_name = 'os_pipe'

def f():
	pread = open(pipe_name, 'r')
	i = 0
	while i<10:
		time.sleep(0.5)
		# 子进程每次读取每行,打印出来,然后主进程停止发送,每次读取为空,直到最终退出循环
		data = pread.readline()[:-1]
		# 这里开始是显示主进程发给子进程,后来主进程不发之后,读取为空
		# getppid()显示2311,是这个进程发空字符串给子进程,
		# 用htop查看2311的command,是init --user,暂时不明白底层实现
		print(os.getppid(), 'send', data,'to', os.getpid())
		i += 1

def g():
	pwrite = os.open(pipe_name, os.O_WRONLY)
	i = 0
	while i<5:
		time.sleep(1)
		# 主进程一次一停发到管道,加上换行符
		os.write(pwrite, bytes(str(i)+'\n', encoding='utf-8'))
		# 这里显示父进程发给子进程
		print(os.getpid(), 'sent', str(i), 'to', pid)
		i += 1

if not os.path.exists(pipe_name):
	os.mkfifo(pipe_name)

# 这里用fork创建子进程,子进程读消息,主进程写消息
pid = os.fork()
if pid != 0:
	g()
	# 这里加上time.sleep()去等待子进程,反而会阻塞子进程接收空字符串,
	# 看来只有等父进程结束后,子进程再继续尝试接收字符串,
else:
	f()

# 这个done被调用两次,先是主进程结束,再是父进程结束
print('done')

然后是,子进程发给父进程,这种的就正常了

#!/usr/bin/python3.6

import time, os

pipe_name = 'os_pipe'

def f():
	pread = open(pipe_name, 'r')
	i = 0
	while i<10:
		time.sleep(0.5)
		data = pread.readline()[:-1]
		# 显示子进程发给主进程空字符串,显示正常,直到退出循环
		print(pid, 'send', data,'to', os.getpid())
		i += 1

def g():
	pwrite = os.open(pipe_name, os.O_WRONLY)
	i = 0
	while i<5:
		time.sleep(1)
		# 子进程一次一停发到管道
		os.write(pwrite, bytes(str(i)+'\n', encoding='utf-8'))
		# 这里显示子进程发给父进程
		print(os.getpid(), 'sent', str(i), 'to', os.getppid())
		i += 1

if not os.path.exists(pipe_name):
	os.mkfifo(pipe_name)

# 这里用fork创建子进程,主进程读消息,子进程写消息
pid = os.fork()
if pid != 0:
	f()
else:
	g()
	
print('done')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值