返回

python 子进程和父进程参数传递

发布时间:2023-10-20 15:11:35 319


最近遇到了一个非常麻烦的问题: 复杂的讲, 由于对grpc的了解仅是皮毛, 导致grpc的服务端收到数据后, 没有办法直接使用这些数据, 因为项目中运行grpc服务端被本人封到了一个类一个子进程中, 如下图所示, 本来希望定义一个全局变量global, 然后通过grpc服务端得到数据, 在从主函数中(父进程)中使用这个全局变量的数据, 但是无论进行怎样的尝试都无法实现, 调试了一天, 总觉得是我的语法或者代码逻辑有问题, 直到我查看了一个博客, 写明了一句话 创建进程的时候, 会把资源和全局变量统统拷贝一波, ​​不会跟父进程共享变量​​ 我傻了呀我, 根据这个线索, 我继续捋顺了一下, 终于查到了需要怎么解决, 那就是下文提到的 ​​from multiprocessing import Manager​

python 子进程和父进程参数传递_python

简答来讲:

  1. 创建进程, 不管全局还是局部变量, 子进程都统统深拷贝了一份
  2. 想要进程间共享参数, 可以使用 ​​from multiprocessing import Process, Manager​
  3. 下面给出实验以及使用

​​献上我之前写的python的进程和线程​​

实验1 普通的全局变量在进程间不可用

import numpy as np
import random
import time # 设置系统延时,

from multiprocessing import Process, Manager # 多进程执行tvm的server

# mdata = Manager().dict() # 创建一个全局dict, 这个全局的dict就可以在进程间通信

tvm_data = {}
tvm_data["action"] = 0

# tvm_data是一个字典 state, reward, action, maxLen,
def subprocess1():
global tvm_data
while True:
for _ in range(1000):
print("fun action = ",tvm_data["action"])
tvm_data["action"] = _
time.sleep(1)


def main():
global tvm_data
p1 = Process(target=subprocess1, args=())
p1.start()
while True:
tvm_data["action"] = 0
print("main action = ",tvm_data["action"])
time.sleep(2)
main()
'''
main action = 0
fun action = 0
fun action = 0
main action = 0
fun action = 1
fun action = 2
main action = 0
fun action = 3
fun action = 4
main action = 0
fun action = 5
fun action = 6
main action = 0
fun action = 7
'''

实验2 使用Manger创建的字典, 在子进程中调用, 有效

import numpy as np
import random
import time # 设置系统延时,

from multiprocessing import Process, Manager # 多进程执行tvm的server

mdata = Manager().dict() # 创建一个全局dict, 这个全局的dict就可以在进程间通信
mdata["action"] = 0

tvm_data = {}
tvm_data["action"] = 0

# tvm_data是一个字典 state, reward, action, maxLen,
def subprocess1():
global tvm_data
while True:
for _ in range(1000):
print("fun action = ",tvm_data["action"])
tvm_data["action"] = _
time.sleep(1)

def subprocess2():
while True:
for _ in range(1000):
print("fun action = ",mdata["action"])
mdata["action"] += 1
time.sleep(0.5) # 在这2s内增加4

def main():
global tvm_data
p1 = Process(target=subprocess2, args=())
p1.start()
while True:
print("main action = ",mdata["action"])
mdata["action"] = 0
time.sleep(2)
main()
'''
main action = 0
fun action = 0
fun action = 1
fun action = 2
fun action = 3
main action = 4
fun action = 0
fun action = 1
fun action = 2
fun action = 3
main action = 4
fun action = 0
fun action = 1
fun action = 2
fun action = 3
main action = 4
fun action = 0
fun action = 1
fun action = 2
fun action = 3
main action = 4
fun action = 0
fun action = 1
'''

总结

Manager支持的类型有

​list,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value和Array​

但当使用​​Manager​​​处理​​list、dict​​​等可变数据类型时,需要注意一个陷阱,即​​Manager​​​对象无法监测到它引用的可变对象值的修改,需要通过触发​​__setitem__​​方法来让它获得通知。

而触发​​__setitem__​​方法比较直接的办法就是增加一个中间变量,如同在C语言中交换两个变量的值一样:

int a=1, b=2;
int tmp=a;
a=b;
b=tmp;

所以如果想要进程间使用全局变量, 只需要利用​​manager​​定义变量即可


特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线
下一篇
C++设计模式 迭代器模式 2023-10-20 11:59:00