python 线程池不等待进程结束
python threadpool not waiting for process to end
我玩多处理已经有一段时间了,有些事情让我很困惑。
我写了这个简单的代码来说明问题:
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
您感到困惑的部分原因是您正在尝试启动 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 秒任务线程的两倍。
我玩多处理已经有一段时间了,有些事情让我很困惑。 我写了这个简单的代码来说明问题:
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
您感到困惑的部分原因是您正在尝试启动 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 秒任务线程的两倍。