参考博客:https://blog.csdn.net/u013066730/article/details/105821979

信安赛以前没试过这样的开发,这次信安赛的作品涉及并发编程,就记录记录呢。
大体逻辑是:主进程运行Flask框架,子进程跑检测数字人的模型,子进程的参数应该传递到主进程中才能实时显示到前端
还学了怎么在浏览器的控制台debug前端JS脚本hhh

1.关于进程里的全局变量

import multiprocessing
import time
list1=[] #list1是一个全局变量
def write():
for i in range(5):
list1.append(i)
time.sleep(1)
def read():
print(list1)
if __name__=="__main__":
t1=multiprocessing.Process(target=write)
t2=multiprocessing.Process(target=read)
t1.start()
t1.join #让t1运行完在运行t2
t2.start()

执行上述进程可以看到t1列表中有值,而t2列表还是一个空值列表,所以由此可见在不同的进程中它们是不共享全局变量的,只有在线程中才共享全局变量。

2.多进程通信

一个demo:

# -*- coding:utf-8 -*-
from multiprocessing import Process, Manager
import time
import random
def kkk(a_list, number):
for i in range(10):
a_list.append(np.array([i]))
time.sleep(random.randrange(2))
print('这是进程{} {}'.format(number, a_list))
print('这是进程{} {}'.format(number, a_list))
def jjj(a_list):
for i in range(2):
process = Process(target=kkk, args=(a_list, i))
process.start()
if __name__ == '__main__':
manager = Manager()
a_list = manager.list()
# a_list = []
process_0 = Process(target=jjj, args=(a_list,))
process_0.start()
process_0.join()
print(a_list)
print(len(a_list))
print('it\'s ok')

由于进程之间数据是不共享的,所以不会出现多线程GIL带来的问题。多进程之间的通信通过Queue()或Pipe()来实现

2.1.1.Queue()

使用方法跟threading里的queue差不多

from multiprocessing import Process, Queue

def f(q):
q.put([42, None, 'hello'])

if __name__ == '__main__':
q = Queue()
p = Process(target=f, args=(q,))
p.start()
print(q.get()) # prints "[42, None, 'hello']"
p.join()

2.1.2.Pipe()

Pipe的本质是进程之间的数据传递,而不是数据共享,这和socket有点像。pipe()返回两个连接对象分别表示管道的两端,每端都有send()和recv()方法。如果两个进程试图在同一时间的同一端进行读取和写入那么,这可能会损坏管道中的数据。

from multiprocessing import Process, Pipe

def f(conn):
conn.send([42, None, 'hello'])
conn.close()

if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv()) # prints "[42, None, 'hello']"
p.join()

2.2 Manager

通过Manager可实现进程间数据的共享。Manager()返回的manager对象会通过一个服务进程,来使其他进程通过代理的方式操作python对象。manager对象支持 list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value ,Array.

from multiprocessing import Process, Manager

def f(d, l):
d[1] = '1'
d['2'] = 2
d[0.25] = None
l.append(1)
print(l)

if __name__ == '__main__':
with Manager() as manager:
d = manager.dict()

l = manager.list(range(5))
p_list = []
for i in range(10):
p = Process(target=f, args=(d, l))
p.start()
p_list.append(p)
for res in p_list:
res.join()

print(d)
print(l)