如何将funcA.py改为函数式调用以控制pool.py运行进程?
问题描述
我用Python写了pool.py、funcA.py、config.py三个文件,要实现跨进程交互:
- pool.py通过while循环模拟常驻进程
- 单独运行funcA.py时会阻塞进程
- config.py定义全局变量
cmd0和cmd1,funcA.py负责修改这两个变量,pool.py持续读取并检测变量变化 - 测试时在两个终端分别运行pool.py和funcA.py,修改funcA.py里的变量后,pool.py的输出会即时更新
现在需要把funcA.py改写成函数,直接调用这个函数就能修改另一个终端中运行的pool.py的输出效果。
原文件代码
config.py
def init(): global cmd0, cmd1 cmd0 = '' cmd1 = '' return cmd0, cmd1
pool.py
import os import time import sys import numpy as np import config import funcA from importlib import reload while True: funcA = reload(funcA) print(str(config.cmd0)) print(str(config.cmd1)) if config.cmd0 == 'start': print('stop') time.sleep(10)
funcA.py
import os import sys import numpy as np import config config.cmd0 = 'start' config.cmd1 = 'u1'
解决方案
首先得明确:不同终端的进程是独立的,内存空间完全隔离,原来靠修改funcA.py文件+reload模块的方式只是个hack——本质是pool.py自己重新执行了修改后的代码,根本不是真正的跨进程通信。要实现调用函数就能修改另一个进程的变量,必须用**跨进程通信(IPC)**机制,下面给出基于本地文件的极简实现(无额外依赖):
1. 改造config.py:换成文件存储变量
把原来的全局变量改成读写文件的接口,让两个进程能通过文件共享数据:
import json import os # 存储配置的文件路径,可自行修改 CONFIG_FILE = "./cmd_config.json" def init(): # 初始化配置文件,不存在则创建 if not os.path.exists(CONFIG_FILE): with open(CONFIG_FILE, 'w') as f: json.dump({"cmd0": "", "cmd1": ""}, f) def get_cmd(): # 读取当前配置 with open(CONFIG_FILE, 'r') as f: data = json.load(f) return data["cmd0"], data["cmd1"] def set_cmd(cmd0, cmd1): # 写入新配置 with open(CONFIG_FILE, 'w') as f: json.dump({"cmd0": cmd0, "cmd1": cmd1}, f)
2. 改造pool.py:从文件读取变量
不再依赖reload模块,直接循环读取共享文件的内容:
import time import config # 初始化配置文件 config.init() while True: cmd0, cmd1 = config.get_cmd() print(f"cmd0: {cmd0}") print(f"cmd1: {cmd1}") if cmd0 == 'start': print('stop') time.sleep(10) # 加个短休眠,避免频繁读文件占资源 time.sleep(0.5)
3. 改造funcA.py:写成可调用的函数
现在可以直接调用函数修改配置,修改后pool.py会立刻感知到:
import config def update_cmd(new_cmd0, new_cmd1): """修改共享配置的函数""" config.set_cmd(new_cmd0, new_cmd1) print(f"配置已更新:cmd0={new_cmd0}, cmd1={new_cmd1}") # 直接运行脚本时,支持命令行传参调用 if __name__ == "__main__": import sys if len(sys.argv) != 3: print("使用方式:python funcA.py <cmd0值> <cmd1值>") print("示例:python funcA.py start u1") sys.exit(1) update_cmd(sys.argv[1], sys.argv[2])
4. 测试步骤
- 第一个终端运行:
python pool.py,会持续打印当前的cmd0和cmd1 - 第二个终端调用函数:
- 方式1:直接运行脚本传参:
python funcA.py pause u2 - 方式2:在Python交互环境调用:
import funcA funcA.update_cmd("start", "u1")
- 方式1:直接运行脚本传参:
- 回到第一个终端,就能看到输出已经即时更新
其他可选方案
如果需要更高性能,可以用Pythonmultiprocessing模块的Value实现共享内存,或者用Redis作为中间存储(适合多机器/多进程场景),核心都是让两个进程能访问同一份共享数据。
内容的提问来源于stack exchange,提问作者chpiero
相关产品推荐
相关产品推荐

