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')