【脚本语言系列】关于进程间通讯(Python)

本文深入探讨了Python中进程间通讯的多种方式,包括使用信号处理程序进行异步事件管理,利用内存映射文件实现进程间的数据共享。文章还提供了如何避免无限等待和处理信号异常的实用代码示例。

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

如何进行进程间通讯

signal-为异步事件设置处理程序

定义

在Python中使用信号处理程序的机制。
Python信号处理程序不会在底层 C 信号处理程序中执行。相反,低级信号处理程序设置一个标志,通知虚拟机稍后执行相应的Python信号处理程序。
Python信号处理程序总是在主Python线程中执行,即使信号是在另一个线程中接受的。信号不能作为线程间通讯的手段,可以使用threading模块中的同步功能。
此外,只允许主线程设置新的信号处理程序。

样例

  • 限制等待打开文件所花费的时间,避免文件用于可能未打开的串行设备,这通常会导致os.open()无限期挂起。在打开文件之前设置5秒钟的警报;如果操作时间过长,将发送警报信号,并且处理程序引发的异常。
import signal, os

def handler(signum, frame):
	print("Signal handler called with signal", signum)
	raise OSError("Couldn't open device!")

# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM,handler)
signal.alarm(5)

# This open() may hang indefinitely
fd = os.open('/dev/ttyS0', os.O_RDWR)

signal.alarm(0)
  • 处理将程序输出到head(1)等工具将导致在sigpipe标准输出的接收器提前关闭时将信号发送到进程,导致例外的情况——包装入口点以捕获词异常;不要设置SIGPIPE的处理SIG_DFL,以避免BrokenPipeError,这样做会导致程序在程序写入时任何套接字中断连接时意外退出。
import os
import sys

def main():
	try:
		for x in range(10000):
			print("y")
		sys.stdout.flush()
	except BrokenPipeError:
		devnull = os.open(os.devnull, os.O_WRONLY)
		os.dup2(devnull, sys.stdout.fileno())
		sys.exit(1)

if __main__ == "__main__":
	main()

mmap-内存映射文件支持

定义

内存映射文件对象的行为类似于字符串和文件对象。然而,与普通的字符串对象不同,这些是可变的。您可以在大多数需要字符串的地方使用mmap对象,包括:

  • 使用该re模块搜索内存映射文件
  • 由于它们是可变的,通过执行更改单个字符
  • 由于它们是可变的,通过分配切片来更改子字符串
  • 从当前文件位置开始读取和写入数据
  • 通过文件读取和写入不同的位置

内存映射文件由mmap构造函数创建,在Unix和Windows上不同。在任何一种情况下,您都必须为打开以进行更新的文件提供文件描述符。如果要映射现有的Python文件对象,请使用其fileno()方法获取fileno参数的正确值 。否则,您可以使用os.open()函数打开文件,该 函数直接返回文件描述符(完成后仍需要关闭文件)。

样例

  • 上下文管理器
import mmap

with open("hello.txt","wb") as f:
	f.write(b"Hello Python!\n")

with open("hello.txt","r+b") as f:
	mm = mmap.mmap(f.fileno(), 0)
	print(mm.readline())
	print(mm[:5])
	mm[6:] = b" world!\n"
	mm.seek(0)
	print(mm.readline())
	mm.close()
  • 创建匿名映射并在父进程和子进程之间交换数据
import mmap
import os

mm = mmap.mmap(-1,13)
mm.write(b"Hello World!")
#with mmap.mmap(-1,13) as mm:
#	mm.write(b"Hello World!")

pid = os.fork()

if pid == 0:
	mm.seek(0)
	print(mm.readline())

	mm.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值