簡體   English   中英

Python 多處理進程共享數組

[英]Python Multiprocessing Process Shared Array

我有使用Process的 python 代碼:

def RunCode(jobs):
    jobs.remove(multiprocessing.current_process().name)
    print("Name: {}".format(multiprocessing.current_process().name))
    print("len: {}".format(len(jobs)))

def randomString(stringLength=10):
    """Generate a random string of fixed length """
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(stringLength))

if __name__ == '__main__':
    jobs = []

    while True:
        if len(jobs) < 5:
            p = multiprocessing.Process(target=RunCode,args=(jobs,),name="process-camera-{}".format(randomString())) 
            jobs.append(p.name)
            p.start()

我想在進程之間共享jobs數組,因此運行的進程不會超過 5 個。 但似乎當我刪除RunCode function 中的字符串時不會影響主數組。 知道有什么問題嗎?

首先調用非阻塞 function p.start()不足以保證在下次調用之前調用jobs.remove()

其次,即使您要求顯式p.join()作為循環中的最后一行代碼, jobs可能在您的操作系統上的 fork 期間被深度復制,因此第一次迭代有效地刪除了第一個條目,第二個得到具有一個條目的作業版本,因此它僅從其自己的join副本中刪除自己並顯示一個條目,依此類推...

這段代碼更清楚一點:

import multiprocessing
import string
import random

def RunCode(jobs):
    print("Name: {}".format(multiprocessing.current_process().name))
    print("len: {}".format(len(jobs)))
    jobs.remove(multiprocessing.current_process().name)
    print("len: {}".format(len(jobs)))

def randomString(stringLength=10):
    """Generate a random string of fixed length """
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(stringLength))

if __name__ == '__main__':
    jobs = []

    while True:
        if len(jobs) < 5:
            p = multiprocessing.Process(target=RunCode,args=(jobs,),name="process-camera-{}".format(randomString())) 
            jobs.append(p.name)
            p.start()
            p.join()

輸出:

Name: process-camera-xdmlyloget
len: 1
len: 0
Name: process-camera-whwgmxbgrs
len: 2
len: 1
Name: process-camera-jbhzrsdtqg
len: 3
len: 2
Name: process-camera-oprinyvlkl
len: 4
len: 3
Name: process-camera-kyaafxiaoz
len: 5
len: 4

您不能在進程之間共享可修改的標准數據結構。 您必須使用隊列/管道在進程之間進行通信,或者使用https://docs.python.org/3/library/multiprocessing.html#sharing-state-between-processes中描述的基於內存映射的數據結構

嚴格來說,這不是問題的答案,但我沒有發表評論而不是答案的聲譽,所以我必須把它放在這里。

看起來您正在重建 Python 的concurrent.futures模塊的很多 function。 改用它可能會更好。 它允許您創建一個具有最大進程數(在您的情況下為 5 個)的進程池,然后將作業傳遞給該池,該池會將它們交給可用的進程或將它們放入隊列中,直到有可用的進程。

您可能會使用如下所示的代碼來實現您所需要的:

from concurrent import futures

def do_thing(arg):
    """This is where you do the thing you want done in other processes."""
    return arg, arg ** arg

ex = futures.ProcessPoolExecutor(max_workers=5)

done = []

for i in range(100):
    done.append(ex.submit(do_thing, i))

for thing in done:
    num, exp = thing.result()
    print(f'{num}**{num} = {exp}')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM