Python 使用ThreadPoolExecutor实现合并排序
我是python的初学者,我已经开始尝试python 3.4。下面是我对多线程合并排序的尝试。但似乎当执行器的线程用完时,submit会阻塞我知道这个设计一开始就错了。我的问题是,如果池中没有空闲线程可供使用,是否有安全的非阻塞替代方案继续使用当前线程Python 使用ThreadPoolExecutor实现合并排序,python,python-3.x,python-3.4,Python,Python 3.x,Python 3.4,我是python的初学者,我已经开始尝试python 3.4。下面是我对多线程合并排序的尝试。但似乎当执行器的线程用完时,submit会阻塞我知道这个设计一开始就错了。我的问题是,如果池中没有空闲线程可供使用,是否有安全的非阻塞替代方案继续使用当前线程 from concurrent.futures.thread import ThreadPoolExecutor def merge(left_slice, right_slice): lindex = 0 rindex = 0
from concurrent.futures.thread import ThreadPoolExecutor
def merge(left_slice, right_slice):
lindex = 0
rindex = 0
result = []
while lindex != len(left_slice) or rindex != len(right_slice):
if lindex == len(left_slice):
result = result + right_slice[rindex:len(right_slice)]
return result
elif rindex == len(right_slice):
result = result + left_slice[lindex:len(left_slice)]
return result
elif left_slice[lindex] < right_slice[rindex]:
result.append(left_slice[lindex])
lindex = lindex + 1
elif left_slice[lindex] > right_slice[rindex]:
result.append(right_slice[rindex])
rindex = rindex + 1
else:
result.append(right_slice[rindex])
rindex = rindex + 1
result.append(left_slice[lindex])
lindex = lindex + 1
return result
def sort(numbers):
"""merge sort"""
if len(numbers) == 1:
return numbers
left_slice = numbers[0:len(numbers)//2]
right_slice = numbers[len(numbers)//2:len(numbers)]
left_future = executor.submit(sort, left_slice)
right_future = executor.submit(sort, right_slice)
left_slice = left_future.result()
right_slice = right_future.result()
return merge(left_slice, right_slice)
if __name__ == '__main__':
import random
unsorted = random.sample(range(1000000), 10000 )
import time
print ("starting to sort...")
start = time.time();
with ThreadPoolExecutor(max_workers=5) as executor:
future = executor.submit(sort, unsorted)
print(future.result()[-5:])
print("done sorting: " + time.time() - start)
.提交未被阻止。结果是,@Kevin也许你是对的。你能分享一下你提到提交是非屏蔽的参考资料吗?无论如何,我认为问题在于排序的递归最终将消耗池中的所有线程,并且submit或result将挂起等待线程变为空闲。当我增加max_workers的值时,我可以验证它没有挂起。请看:submit不执行任何操作,它只是调度执行并立即返回。这里通常的设计是只在一些主线程上检索结果,但我不确定如何将其应用于像mergesort这样的递归算法。不管怎样,还是穿线。@Kevin哇,GIL太差劲了。感谢这两个链接。如果您有I/O工作要写/读文件、联网等,线程仍然很有用,因为I/O操作通常会释放GIL。有些库(如NumPy)也可以从线程中获益,因为它们使用本机C代码进行工作。