python threadpool没有等待进程结束

时间:2017-04-26 16:10:22

标签: python multithreading python-2.7 optimization threadpool

我现在一直在玩多处理,有些东西让我感到困惑。 我写了这个简单的代码来说明问题:

from multiprocessing.pool import ThreadPool #I import the packages needed
from time import sleep

def long_task(n): #a simple long task
    sleep(1)
    print str(n)+" task finished"


pool = ThreadPool(8) #define my threadpool

for x in xrange(10**7): #it could be a while loop too
    print x
    pool.apply_async(long_task, args=(x,))

for循环内部我希望我的代码等到8个线程中的一个完成后再启动另一个,但是x正在打印而没有任何中断。 为什么会这样?我如何得到我正在寻找的东西?这段代码是否经过优化?

示例输出:

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14

1 个答案:

答案 0 :(得分:1)

您遇到的部分困惑是您正在尝试启动10**7任务。为了实验,将其减少到一些合理的数字,比如说30。您的输出现在是

0
1
2
...
27
28
29

然后,大约一秒钟之后,类似

2 task finished3 task finished
0 task finished1 task finished


5 task finished4 task finished6 task finished


7 task finished

文本将全部乱码,在我的情况下,换行符通常分批打印。这是因为对print的调用未正确同步。下一批将在大约一秒后打印出来:

13 task finished
11 task finished9 task finished8 task finished12 task finished
10 task finished

类似于第三批。最后一批只包含最后6个输出(24-30):

24 task finished
25 task finished
26 task finished
29 task finished27 task finished

28 task finished

要记住的是,任务立即计划。这是线程池的目的。这意味着它们只会被添加到稍后运行的事物列表中,这就是您立即看到x打印输出的原因。正如您所料,这些任务实际上一次运行八个。实际上,第一批之后的任务是在线程可用时逐个启动的,但由于它们几乎完全相同的时间,看起来好像它们是批量运行。

你可以设置一个实验来看看当你的一半任务需要1秒钟运行而一半需要2秒时会发生什么。虽然它们将按照您将它们添加到队列的顺序立即启动,但1秒任务的线程将比2秒任务的线程快两倍。