当前位置 : 主页 > 网络编程 > PHP >

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

来源:互联网 收集:自由互联 发布时间:2023-09-07
最近遇到了一个非常麻烦的问题: 复杂的讲, 由于对grpc的了解仅是皮毛, 导致grpc的服务端收到数据后, 没有办法直接使用这些数据, 因为项目中运行grpc服务端被本人封到了一个类一个子进


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

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​​定义变量即可


【文章原创作者:阿里云代理 http://www.558idc.com/aliyun.html处的文章,转载请说明出处】
上一篇:C++设计模式1 三种工厂模式
下一篇:没有了
网友评论