Python中使用共享变量+信号量实现进程间的实时通信

多进程共享内存(如 multiprocessing.Valuemultiprocessing.Array

  • 如果使用 multiprocessing 模块创建共享变量,这些变量通常只在同一进程池中的进程之间共享。因此,不同的 Python 环境(即不同的 Python 解释器运行的环境)无法直接访问这些共享变量。
  • 这种方式的共享变量一般是进程内的,不会跨环境工作。如果尝试在另一个 Python 环境中访问它,通常会抛出错误,提示该共享变量不存在或不可访问

共享内存(posix_ipc.SharedMemory

  • 如果使用的是 posix_ipc 或类似的库创建共享内存,其他 Python 程序(在同一台计算机上)也可以通过相同的共享内存名称来访问该内存。这是因为共享内存是系统级的资源,不依赖于单个进程的生命周期。
  • 只要所有程序都使用正确的名称并确保有访问权限,另一个 Python 环境(另一个Python解释器运行的Python文件)应该能够成功访问共享内存,不会出错




方法一:使用Multiprocessing
【Python程序1中】

import ctypes
import posix_ipc
import multiprocessing
from multiprocessing import shared_memory

# 如果系统中已经存在名为 /semaphore1 的信号量对象,Python并不会重新初始化它,而是使用现有的信号量,
# 导致现有的信号量可能有残留状态,使得 acquire() 一直阻塞。
# 在创建信号量之前,先删除现有的同名信号量
try:
  posix_ipc.unlink_semaphore("/semaphore1")
except posix_ipc.ExistentialError:
  pass # 如果信号量不存在,忽略错误

# 创建具名信号量(其他进程可以使用同样的名称 "/semaphore1" 来访问),1表示有物品,0表示没物品
# 注意,需要intial_value = 1,这样信号量一开始才会有一个
# 使用 O_EXCL 标志来强制创建一个新的信号量
sem = posix_ipc.Semaphore("/semaphore1", flags=posix_ipc.O_CREAT | posix_ipc.O_EXCL, initial_value=1)
# 创建一个大小为 ctypes.c_int 所需的共享内存块
shm = shared_memory.SharedMemory(create=True, size=ctypes.sizeof(ctypes.c_int), name="steel")
# 使用 ctypes 将共享内存映射为一个整数
shared_int = ctypes.c_int.from_buffer(shm.buf)

sem.acquire() # 获取信号量
###########需要执行的操作 ####################

if (out1 == True):
  # 检测到有输入
  shared_int.value = 1
else:
  shared_int.value = 0

############ 需要执行的操作 #####################

sem.release() # 释放信号量

# 释放共享内存
shm.close()
shm.unlink()

# 删除信号量(通常由创建信号量的进程负责清理)
sem.unlink()


【Python程序2中】

import posix_ipc
from multiprocessing import shared_memory, resource_tracker
import ctypes


# 链接信号量
sem = posix_ipc.Semaphore("/semaphore1")
# 连接到名为 "steel" 的共享内存块
shm = shared_memory.SharedMemory(name="steel")
# 使用 ctypes 将共享内存映射为一个整数
shared_int = ctypes.c_int.from_buffer(shm.buf)
# 取消资源跟踪,在另一个程序1中会释放这个共享内存
resource_tracker.unregister(shm._name, "shared_memory")

sem.acquire() # 获取信号量
########## 待执行操作#################################

if shared_int.value ==1:
  message = "True"
else:
  message = "False"

########### 待执行操作###############################

sem.release() # 释放信号量

方法二:使用Posix_ipc

【Python程序1中】

import posix_ipc
import mmap
import time

# 如果系统中已经存在名为 /semaphore1 的信号量对象,Python并不会重新初始化它,而是使用现有的信号量,
# 导致现有的信号量可能有残留状态,使得 acquire() 一直阻塞。
# 在创建信号量之前,先删除现有的同名信号量
try:
  posix_ipc.unlink_semaphore("/semaphore1")
except posix_ipc.ExistentialError:
  pass # 如果信号量不存在,忽略错误

# 创建具名信号量(其他进程可以使用同样的名称 "/semaphore1" 来访问),1表示有物品,0表示没物品
# 注意,需要intial_value = 1,这样信号量一开始才会有一个
# 使用 O_EXCL 标志来强制创建一个新的信号量
sem = posix_ipc.Semaphore("/semaphore1", flags=posix_ipc.O_CREAT | posix_ipc.O_EXCL, initial_value=1)

# 创建共享内存,指定名称和大小
shm = posix_ipc.SharedMemory("/my_shared_memory", flags=posix_ipc.O_CREAT, size=1024)

# 获取共享内存的内存缓冲区

memory = mmap.mmap(shm.fd, shm.size)

sem.acquire() # 获取信号量

# 向共享内存写入数据

memory[:5] = b'hello'

sem.release() # 释放信号量

# 关闭共享内存

memory.close()

shm.close_fd()
【Python程序2中】

import posix_ipc
import mmap

# 链接信号量
sem = posix_ipc.Semaphore("/semaphore1")

# 打开已存在的共享内存
shm = posix_ipc.SharedMemory("/my_shared_memory")

# 获取共享内存的内存缓冲区

memory = mmap.mmap(shm.fd, shm.size)

# 链接信号量
sem.acquire()

# 读取共享内存中的数据
print(memory[:5]) # 输出 b'hello'

sem.release() # 释放信号量

# 关闭共享内存
memory.close()
shm.close_fd()
posted @ 2024-10-29 20:19  碳酸钾K2CO3  阅读(234)  评论(0)    收藏  举报