背景 & 方案适用场景
Python中可以直接使用Multiprocessing包开启多进程,并使用包中的Queue实现进程间的异步通信。
但是如果需要通信的进程已经被封装,或者是其他语言写的程序,又要实现进程间异步通信,可以参考本文的方案:读写FIFO文件。
*注:除本方案外,想实现不同语言的进程进行通信,也可以使用socket通信等方式
实现进程间异步通信
主要用到以下工具包:
# 用Process类管理多进程
import multiprocessing import Process
# 导入系统工具
import fcntl
import os
写FIFO进程
def productor() -> None:
while True:
'''
其他要在进程中实现的逻辑
'''
try:
msg = "Hello, World!"
fifo_fd = os.open("./tmp_pipe", os.O_WRONLY)
os.write(fifo_fd, msg.encode())
os.close(fifo_fd)
except OSError:
pass
'''
其他要在进程中实现的逻辑
'''
# 防止重复写入fifo过快造成打开失败,如果间隔的逻辑比较多,可以不加入sleep
time.sleep(1)
读FIFI进程
def customer() -> None:
while True:
'''
其他要在进程中实现的逻辑
'''
try:
fifo_fd = os.open("./tmp_pipe", os.O_RDONLY | os.O_NONBLOCK)
fcntl.fcntl(fifo_fd, fcntl.F_SETFL, os. O_NONBLOCK)
msg = os.read(fifo_fd, 1024)
'''
其他要在进程中实现的逻辑
'''
os.close(fifo_fd)
except OSError:
pass
主调用进程
def main() -> None:
if not os.path.exists("./tmp_pipe"):
os.mkfifo("./tmp_pipe")
p_productor = Process(target=productor)
p_customer = Process(target=customer)
p_writer.start()
p_customer.start()
timeout = 100
time.sleep(100)
p_productor.kill()
p_customer.kill()
os.unlink("./tmp_pipe")
问题 & 解决方案
本文中实现了一个生产者消费者模型,在这个情况下会出现一个进程阻塞的问题:fifo空,消费者再读fifo实现后续逻辑时,消费者进程会被阻塞在open fifo一行,所以上述代码使用了如下方式防止阻塞:
fifo_fd = os.open("./tmp_pipe", os.O_RDONLY | os.O_NONBLOCK)
fcntl.fcntl(fifo_fd, fcntl.F_SETFL, os. O_NONBLOCK)