我有一个API侦听传入的请求并将其转储到列表中。 在单独的过程中,每当追加列表时,我都想触发某种操作。我尝试实例化一个新进程(通过多重处理),但是一旦启动,它就不会更新数组的状态。
from multiprocessing import Process
import time
procs = []
def separateProcess(start, counter):
while True:
time.sleep(1)
print("length of the list from separate Process: "+str(len(procs)))
if __name__ == '__main__':
print("program started")
counter = 0
Process(target=separateProcess, args=(counter, counter)).start()
print("program end")
while True:
counter += 1
newstring = "string "+str(counter)
procs.append(newstring)
print("length of the list from main: " + str(len(procs)))
time.sleep(2)
这是输出:
length of the list from main: 1
length of the list from separate Process: 0
length of the list from main: 2
length of the list from separate Process: 0
length of the list from separate Process: 0
length of the list from main: 3
length of the list from separate Process: 0
length of the list from separate Process: 0
答案 0 :(得分:1)
创建一个新的子进程时,它将获得父进程地址空间的副本,但是随后的任何更改(无论是父进程还是子进程)都不会反映在另一个进程的内存中。他们每个人都有自己的专用地址空间。
您可以创建一个Manager()并使用其共享的list对象:
import time
from multiprocessing import Manager, Process
def separateProcess(start, counter):
while True:
time.sleep(1)
print("length of the list from separate Process: "+str(len(procs)))
if __name__ == '__main__':
m = Manager()
procs = m.list()
print("program started")
counter = 0
Process(target=separateProcess, args=(counter, counter)).start()
print("program end")
while True:
counter += 1
newstring = "string "+str(counter)
procs.append(newstring)
print("length of the list from main: " + str(len(procs)))
time.sleep(2)
此方法会产生一些开销,因为它将产生一个子代进程来托管Manager
服务器。
如果您可以调整工作进程逻辑以改为使用队列,请参见以下示例:
import random
import time
from multiprocessing import cpu_count, Process, Queue
def worker(q):
for item in iter(q.get, 'STOP'):
t = random.uniform(1, 5)
print(f'START item: {item}')
time.sleep(t)
print(f'END item: {item}, ({t:.3f}s)')
def main():
cpus = cpu_count()
q = Queue()
for i in range(5):
q.put(i)
for i in range(cpus):
Process(target=worker, args=(q,)).start()
for i in range(cpus):
q.put('STOP')
if __name__ == '__main__':
main()