Python多进程:如何从运行程序获取共享变量当前值?
问题描述
我编写了file1.py,通过多进程每秒更新一个共享变量shared_var:
import time from multiprocessing import Value, Lock, Process def update_shared_variable(shared_var, lock): for i in range(100): with lock: shared_var.value = i # 更新共享变量的值 time.sleep(1) print("Updated value in file1:", shared_var.value) if __name__ == '__main__': shared_var = Value('i', 0) lock = Lock() update_process = Process(target=update_shared_variable, args=(shared_var, lock)) update_process.start() update_process.join()
运行后会依次输出Updated value in file1: 0、Updated value in file1: 1等结果。
同时我写了file2.py,试图获取运行中的file1.py里shared_var的当前值:
import time from multiprocessing import Value, Process def get_current_value(shared_var): while True: current_value = shared_var.value print("Current value of x from file1:", current_value) time.sleep(2) if __name__ == '__main__': shared_var = Value('i', 0) # 创建进程获取x的当前值 get_value_process = Process(target=get_current_value, args=(shared_var,)) get_value_process.start() get_value_process.join()
但运行file2.py后,始终输出Current value of x from file1: 0,请问错误原因是什么?怎么在file2.py中获取运行中的file1.py里shared_var的当前值?
错误原因
multiprocessing.Value是进程组内的共享内存对象,它的内存空间只在当前Python解释器进程及其子进程中可见。file1.py和file2.py是两个完全独立的Python进程,各自拥有独立的内存空间,file2里的shared_var只是自己初始化的新实例,根本看不到file1进程里的变量值。
解决方案
方法1:使用命名共享内存(Python 3.8+)
利用multiprocessing.shared_memory创建跨进程可见的命名内存块,让不同进程通过名称访问同一块内存。
修改file1.py:
import time from multiprocessing import Lock, Process from multiprocessing.shared_memory import SharedMemory import struct def update_shared_variable(shm_name, lock): # 连接到已创建的命名共享内存 shm = SharedMemory(name=shm_name, create=False) # 用struct处理整数的字节存储(int占4字节) for i in range(100): with lock: shm.buf[:4] = struct.pack('i', i) time.sleep(1) current_val = struct.unpack('i', shm.buf[:4])[0] print("Updated value in file1:", current_val) shm.close() if __name__ == '__main__': # 创建命名共享内存,大小4字节 shm = SharedMemory(name='MySharedVar', create=True, size=4) # 初始化值为0 shm.buf[:4] = struct.pack('i', 0) lock = Lock() update_process = Process(target=update_shared_variable, args=('MySharedVar', lock)) update_process.start() update_process.join() # 只有创建者需要调用unlink销毁共享内存 shm.unlink()
修改file2.py:
import time from multiprocessing.shared_memory import SharedMemory import struct def get_current_value(shm_name): # 连接到已存在的命名共享内存 shm = SharedMemory(name=shm_name, create=False) while True: current_val = struct.unpack('i', shm.buf[:4])[0] print("Current value of x from file1:", current_val) time.sleep(2) shm.close() if __name__ == '__main__': get_current_value('MySharedVar')
注意:先启动file1.py,再启动file2.py,确保共享内存已被创建。
方法2:使用Redis中间件
借助第三方中间件实现跨进程通信,适合跨机器场景,稳定性高。先安装依赖:pip install redis
修改file1.py:
import time import redis def update_shared_variable(): r = redis.Redis(host='localhost', port=6379, db=0) for i in range(100): r.set('shared_var', i) time.sleep(1) print("Updated value in file1:", i) if __name__ == '__main__': update_shared_variable()
修改file2.py:
import time import redis def get_current_value(): r = redis.Redis(host='localhost', port=6379, db=0) while True: current_val = int(r.get('shared_var')) print("Current value of x from file1:", current_val) time.sleep(2) if __name__ == '__main__': get_current_value()
方法3:文件作为中间存储
最简单的方案,通过文件读写传递变量值,适合小流量场景。
修改file1.py:
import time def update_shared_variable(): for i in range(100): with open('shared_var.txt', 'w') as f: f.write(str(i)) time.sleep(1) print("Updated value in file1:", i) if __name__ == '__main__': update_shared_variable()
修改file2.py:
import time def get_current_value(): while True: try: with open('shared_var.txt', 'r') as f: current_val = int(f.read().strip()) print("Current value of x from file1:", current_val) except FileNotFoundError: print("等待file1创建共享文件...") time.sleep(2) if __name__ == '__main__': get_current_value()
内容的提问来源于stack exchange,提问作者Frank Cowperwood

