Skip to main content
 首页 » 编程设计

python之如何使用分而治之的多线程

2024年12月31日29grandyang

我是 Python 的新手,一直在尝试使用多线程。已经存在一个深入的 comment on Stackoverflow关于这个话题,但我还有一些问题。

我的程序的目标是创建和填充一个数组(尽管我猜从技术上讲它必须在 Python 中称为“列表”)并通过“分而治之”算法对其进行排序。不幸的是,术语“列表”和“数组”似乎被许多用户混为一谈,即使它们并不相同。如果我的评论中使用了“数组”,请记住我发布了来自各种资源的不同代码,并且为了尊重原作者,我没有更改其内容。

我填充列表 count 的代码非常简单

#!/usr/bin/env python3 
count = [] 
i = 149 
while i >= 0: 
    count.append(i) 
    print(i) 
    i -= 1 

之后我使用了this very handy guide在“分而治之”的主题上创建两个列表进行排序,稍后合并。我现在主要关心的是如何通过多线程正确使用这些列表。

在earlier mentioned post有人认为,基本上,使用多线程只需要几行代码:

from multiprocessing.dummy import Pool as ThreadPool  
pool = ThreadPool(4) 

还有

results = pool.starmap(function, zip(list_a, list_b)) 

传递多个列表。

我尝试修改代码但失败了。我的函数的参数是def merge(count, l, m, r)(用于将列表count分成左右两部分)和临时创建的两个列表称为 L 和 R。

def merge(arr, l, m, r):  
    n1 = m - l + 1 
    n2 = r- m  
 
    # create temp arrays  
    L = [0] * (n1)  
    R = [0] * (n2)  

但每次我运行该程序时,它都会返回以下错误消息:

Traceback (most recent call last): 
  File "./DaCcountdownTEST.py", line 71, in <module> 
    results = pool.starmap(merge,zip(L,R)) 
NameError: name 'L' is not defined 

我不知道问题的原因。

非常感谢任何帮助!

请您参考如下方法:

我不确定您的代码到底出了什么问题,但这里有一个完整的 the mergeSort code you linked to 多线程版本的工作示例:

from multiprocessing.dummy import Pool as ThreadPool  
 
# Merges two subarrays of arr[].  
# First subarray is arr[l..m]  
# Second subarray is arr[m+1..r]  
def merge(arr, l, m, r):  
    n1 = m - l + 1 
    n2 = r- m  
 
    # create temp arrays  
    L = [0] * (n1)  
    R = [0] * (n2)  
 
    # Copy data to temp arrays L[] and R[]  
    for i in range(0 , n1):  
        L[i] = arr[l + i]  
 
    for j in range(0 , n2):  
        R[j] = arr[m + 1 + j]  
 
    # Merge the temp arrays back into arr[l..r]  
    i = 0     # Initial index of first subarray  
    j = 0     # Initial index of second subarray  
    k = l     # Initial index of merged subarray  
 
    while i < n1 and j < n2 :  
        if L[i] <= R[j]:  
            arr[k] = L[i]  
            i += 1 
        else:  
            arr[k] = R[j]  
            j += 1 
        k += 1 
 
    # Copy the remaining elements of L[], if there  
    # are any  
    while i < n1:  
        arr[k] = L[i]  
        i += 1 
        k += 1 
 
    # Copy the remaining elements of R[], if there  
    # are any  
    while j < n2:  
        arr[k] = R[j]  
        j += 1 
        k += 1 
 
# l is for left index and r is right index of the  
# sub-array of arr to be sorted  
def mergeSort(arr,l=0,r=None): 
    if r is None: 
        r = len(arr) - 1 
 
    if l < r:  
        # Same as (l+r)/2, but avoids overflow for  
        # large l and h  
        m = (l+(r-1))//2 
 
        # Sort first and second halves 
        pool = ThreadPool(2) 
        pool.starmap(mergeSort, zip((arr, arr), (l, m+1), (m, r))) 
        pool.close() 
        pool.join() 
 
        merge(arr, l, m, r) 

下面是代码的简短测试:

arr = np.random.randint(0,100,10) 
print(arr) 
mergeSort(arr) 
print(arr) 

产生以下输出:

[93 56 55 60  0 28 17 77 84  2] 
[ 0  2 17 28 55 56 60 77 84 93] 

遗憾的是,它似乎确实比单线程版本慢了很多。然而,这种减速是par对于 course当谈到 Python 中的多线程计算绑定(bind)任务时。