收听列表并在附加时做某事
Listen to a list and do something whenever it is appended
我有一个 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
创建新的子进程时,它会获得父进程地址的副本 space,但不会反映任何后续更改(由父进程或子进程进行)在另一个进程的内存中。他们每个人都有自己的私人地址 space.
您可以改为创建 Manager() and use its shared 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()
我有一个 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
创建新的子进程时,它会获得父进程地址的副本 space,但不会反映任何后续更改(由父进程或子进程进行)在另一个进程的内存中。他们每个人都有自己的私人地址 space.
您可以改为创建 Manager() and use its shared 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()