【问题标题】:Python Slicing an Array for Multithreading And Reassembling The Results in Order?Python 对数组进行切片以进行多线程处理并按顺序重新组装结果?
【发布时间】:2019-03-11 18:46:33
【问题描述】:

这可能已经在这里问过了,但我找不到合适的关键字来搜索。

我有一个数组,我想将它们分成块,然后将它们交给线程对每个切片做一些工作并转储结果。

但是,我需要按顺序重新组合每个线程的结果。

我尝试为每个线程传递锁以锁定并将结果转储到另一个数组中,但顺序不正确。我假设是因为每个线程在不同的时间完成。

在 Python 3 中最好的方法是什么?

import threading        
import numpy as np
from queue import Queue

def add(lock, work):
    value = 0
    for v in work:
        #Do some work!
    lock.acquire()  
    result.append(value)
    lock.release()  

a = np. arange(0,100)
result = []
lock = threading.Lock()    
q = Queue()
for i in range(0,a.shape[0],10):
    work = a[i:i+10]
    t = threading.Thread(target=add, args=(lock,work))
    t.start()
    q.put(t)

while q.empty() == False:
    q.get().join()

value = 0
for v in result:
    #Assemble
print(value)

【问题讨论】:

    标签: python multithreading


    【解决方案1】:

    您得到的结果顺序混乱,因为append 将每个结果放在列表的末尾,这可能与线程启动的顺序不同。更好的方法可能是将每个工作人员的索引传递到适当大小的列表中,并让它在完成时将其结果分配到那里。列表具有足够的线程安全性,因此您不需要为此加锁(您的 Queue 也完全没有必要,因为只有主线程与之交互)。

    def add(work, result_index):
        value = 0
        for v in work:
            #Do some work!
        result[result_index] = value
    
    a = np.arange(0,100)
    results = [] 
    threads = []
    for i in range(0,a.shape[0],10):
        work = a[i:i+10]
        results.append(None) # enlarge the results list, so we have room for this thread's result
        t = threading.Thread(target=add, args=(work, i//10))
        t.start()
        threads.append(t)
    
    for t in threads:
        t.join()
    

    我会警告您,如果您的 #Do some work! 代码受 CPU 限制,那么您不太可能从使用多线程中获得太多好处。 CPython 解释器有一个全局解释器锁,可防止多个线程同时运行 Python 代码(这样解释器状态(如对象的引用计数)可以保持一致,而无需每个线程都需要自己的锁)。线程仅对 IO 受限的工作(例如从 Internet 获取大量文档)真正有用。

    对于 CPU 受限的工作,您通常希望改用 multiprocessing。如果这是您需要的,请查看multiprocessing.map,它可以处理进程之间的传递对象并自动将结果重新组合成有序列表。

    【讨论】:

    • 谢谢!最终使用 multiprocessing.map!
    猜你喜欢
    • 2019-07-12
    • 2013-06-21
    • 2013-09-10
    • 2016-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多