【问题标题】:Complete a multithreading parallelize process with k threads用 k 个线程完成一个多线程并行化过程
【发布时间】:2015-08-11 06:22:58
【问题描述】:

3sum 问题定义为 给定:一个正整数k≤20,一个正整数n≤104,以及k 大小为n 的数组,其中包含从−105105 的整数。

返回:For each array A[1..n],输出三个不同的索引1≤p<q<r≤n,如果存在A[p]+A[q]+A[r]=0,否则输出"-1"

Sample Dataset
4 5
2 -3 4 10 5
8 -6 4 -2 -8
-5 2 3 2 -4
2 4 -5 6 8

Sample Output
-1
1 2 4
1 2 3
-1

但是我想使用线程加速代码,为此我正在应用 python 代码

def TS(arr):
    original = arr[:]
    arr.sort()
    n = len(arr)        
    for i in xrange(n-2):
        a = arr[i]
        j = i+1
        k = n-1
        while j < k:
            b = arr[j]
            c = arr[k]
            if a + b + c == 0:
                return sorted([original.index(a)+1,original.index(b)+1,original.index(c)+1])
            elif a + b + c > 0:
                k = k - 1
            else:
                j = j +1
    return [-1]

with open("dataset.txt") as dataset:
   k = int(dataset.readline().split()[0]) 
   for i in xrange(k):
       aux = map(int, dataset.readline().split())
       results = TS(aux)
       print ' ' . join(map(str, results))

我正在考虑创建 k 个线程和一个全局数组输出,但是不知道如何继续开发这个想法

from threading import Thread

class thread_it(Thread):
    def __init__ (self,param):
        Thread.__init__(self)
        self.param = param
    def run(self):
        mutex.acquire()
        output.append(TS(aux))
        mutex.release() 


threads = []  #k threads
output = []   #global answer
mutex = thread.allocate_lock()
with open("dataset.txt") as dataset:
       k = int(dataset.readline().split()[0]) 
       for i in xrange(k):
           aux = map(int, dataset.readline().split())           
           current = thread_it(aux)
           threads.append(current)
           current.start()
           
       for t in threads:
           t.join()
  

在线程中获取results = TS(aux) 的正确方法是什么,然后等待所有线程完成,然后为所有线程使用print ' ' . join(map(str,results))

更新

从控制台运行脚本时遇到此问题

【问题讨论】:

  • 你不能使用线程加速这段代码;你需要使用multiprocessing

标签: python multithreading thread-safety


【解决方案1】:

首先,就像@Cyphase 所说,由于GIL,您无法使用threading 加快速度。每个线程都将在同一个核心上运行。考虑使用multiprocessing 来利用多个内核,multiprocessing 具有与线程非常相似的 API。

其次,即使我们假装 GIL 不存在。将所有内容放在受mutex 保护的关键部分中,您实际上是在序列化所有线程。你需要保护的是对output的访问,所以把处理代码放到临界区之外,让它们同时运行:

def run(self):
    result = TS(aux)
    mutex.acquire()
    output.append(result)
    mutex.release()

但不要重新发明轮子,python标准库提供了一个线程安全的队列,使用它:

try:
    import Queue as queue  # python2
except:
    import queue
output = queue.Queue()

def run(self):
    result = TS(self.param)
    output.append(result)

使用多处理,最终代码如下所示:

from multiprocessing import Process, Queue
output = Queue()

class TSProcess(Process):
    def __init__ (self, param):
        Process.__init__(self)
        self.param = param
    def run(self):
        result = TS(self.param)
        output.put(result)

processes = []  
with open("dataset.txt") as dataset:
       k = int(dataset.readline().split()[0]) 
       for i in xrange(k):
           aux = map(int, dataset.readline().split())           
           current = TSProcess(aux)
           processes.append(current)
           current.start()

       for p in processes:
           p.join()
       # process result with output.get()

【讨论】:

  • 我认为您的意思是 @Cyphase,而不是 cMinor,我认为您的意思是 GIL,而不是 PIL :)。
  • @Cyphase 睡眠剥夺的急性症状 ;)
  • 哦,我明白了:)。顺便说一句,你错过了一个“PIL”:P。
  • 好的,但是我明白添加代码的最终代码会是什么样子?如何在主循环for i in xrange(k): 内调用run(self)
  • @cMinor 我添加了最终代码,使用multiprocessing
猜你喜欢
  • 1970-01-01
  • 2012-04-09
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多