Python2.7 中的多处理
Multiprocessing in Python2.7
在我开始将 "multiprocessing" 模块应用到我的主要代码之前,我试图通过示例更多地了解它,并且我对这段代码中的执行顺序有点困惑。
代码:
import multiprocessing as mp
import time
import os
def square( nums , r , t1 ) :
print ("square started at :")
print ("%.6f" % (time.clock()-t1))
for n in nums :
r.append(n*n)
print ("square endeded at :")
print ("%.6f" % (time.clock()-t1))
def cube ( nums , r , t1 ) :
#time.sleep(2)
print ("cube started at :")
print ("%.6f" % (time.clock()-t1))
for n in nums :
r.append(n*n*n)
print ("cube endeded at :")
print ("%.6f" % (time.clock()-t1))
if __name__ == "__main__" :
numbers = range(1,1000000)
results1 = []
results2 = []
t1 = time.clock()
# With multiprocessing :
p1 = mp.Process(target = square , args = (numbers , results1 , t1))
p2 = mp.Process(target = cube , args = (numbers , results2 , t1))
p1.start()
#time.sleep(2)
p2.start()
p1.join()
print ("After p1.join() :")
print ("%.6f" % (time.clock()-t1))
p2.join()
'''
# Without multiprocessing :
square(numbers , results1 ,t1)
cube(numbers , results2 , t1)
'''
print ("square + cube :")
print ("%.6f" % (time.clock()-t1))
代码输出为:
square started at :
0.000000
square endeded at :
0.637105
After p1.join() :
12.310289
cube started at :
0.000000
cube endeded at :
0.730428
square + cube :
13.057885
我有几个问题:
- 根据上面的代码和时间应该是这个顺序?
广场开始于:
多维数据集开始于:
平方结束于:
多维数据集结束于:
在 p1.join() 之后:
方形 + 立方体:
为什么程序要花这么长时间才能到达 (p1.join()) 尽管它提前几秒完成了 "square"?
换句话说,为什么正方形和立方体需要大约 13 秒到 运行 而实时执行是 0.7 秒!
在我的主要代码中,我想在第一个函数延迟一秒后启动第二个函数(本例中的立方体),所以我试图延迟(time.sleep(1)) 在 "p1.start()" 和 "p2.start()" 之间,但它不起作用,两个函数仍然从 (0.000000s) 开始,然后我将延迟放在 "cube " 函数的开头而且它也没有用,所以我的问题是如何实现这两个功能之间的延迟?
在处理多线程时,各种其他因素都会影响您所看到的内容。由于您实际上是将子流程添加到 OS 的流程管理器中,它们将完全独立于您的 运行ning 程序运行,包括拥有自己的资源、调度优先级、管道等。
1.) 不。原因是每个子进程都有自己的输出缓冲区,它正在写入该缓冲区,该缓冲区被写回父进程。由于您启动了两个子进程,然后告诉父进程阻塞线程直到子进程 p1 完成,因此 p2 子进程在 p1 进程完成之前无法将其缓冲区写入父进程。这就是为什么尽管等待了 12 秒,p2 进程的输出仍然显示 0.7 秒。
2.) 很难确定为什么子进程需要 12 秒才能 运行 它的进程。这可能是您的代码中的某些内容,也可能是其他许多原因,例如一个完全不同的进程劫持了您的 CPU 一段时间。首先,如果您尝试衡量实际时间与进程花费在 CPU 上的时间,那么 time.clock 可能不是您要查找的内容。其他评论者正确地建议使用高性能计数器来准确跟踪时间,以确保您测量时间的方式没有任何奇怪之处。此外,在开始、运行宁和终止一个新进程时,总是有一定程度的开销,虽然肯定不值得 12 秒。确定这 12 秒是否是您可以控制的最佳方法是多次 运行 应用程序,看看总结果时间是否存在很大差异。如果有,则可能是与计算机相关的其他情况运行正在处理它。
3.) 我猜问题出在 time.clock 测量上。 time.clock 调用计算进程在 CPU 上花费了多少时间。由于您正在使用多个进程,因此 time.clock 在进程启动时重置为 0。它是相对时间,不是绝对时间,是相对于进程的生命周期而言的。如果您在进程或休眠线程之间跳转,time.clock 不一定会增加您对绝对时间测量的想法。您应该使用类似 time.time() 或更好的东西,一个高性能计数器来正确跟踪实时。
在我开始将 "multiprocessing" 模块应用到我的主要代码之前,我试图通过示例更多地了解它,并且我对这段代码中的执行顺序有点困惑。
代码:
import multiprocessing as mp
import time
import os
def square( nums , r , t1 ) :
print ("square started at :")
print ("%.6f" % (time.clock()-t1))
for n in nums :
r.append(n*n)
print ("square endeded at :")
print ("%.6f" % (time.clock()-t1))
def cube ( nums , r , t1 ) :
#time.sleep(2)
print ("cube started at :")
print ("%.6f" % (time.clock()-t1))
for n in nums :
r.append(n*n*n)
print ("cube endeded at :")
print ("%.6f" % (time.clock()-t1))
if __name__ == "__main__" :
numbers = range(1,1000000)
results1 = []
results2 = []
t1 = time.clock()
# With multiprocessing :
p1 = mp.Process(target = square , args = (numbers , results1 , t1))
p2 = mp.Process(target = cube , args = (numbers , results2 , t1))
p1.start()
#time.sleep(2)
p2.start()
p1.join()
print ("After p1.join() :")
print ("%.6f" % (time.clock()-t1))
p2.join()
'''
# Without multiprocessing :
square(numbers , results1 ,t1)
cube(numbers , results2 , t1)
'''
print ("square + cube :")
print ("%.6f" % (time.clock()-t1))
代码输出为:
square started at :
0.000000
square endeded at :
0.637105
After p1.join() :
12.310289
cube started at :
0.000000
cube endeded at :
0.730428
square + cube :
13.057885
我有几个问题:
- 根据上面的代码和时间应该是这个顺序?
广场开始于:
多维数据集开始于:
平方结束于:
多维数据集结束于:
在 p1.join() 之后:
方形 + 立方体:
为什么程序要花这么长时间才能到达 (p1.join()) 尽管它提前几秒完成了 "square"?
换句话说,为什么正方形和立方体需要大约 13 秒到 运行 而实时执行是 0.7 秒!在我的主要代码中,我想在第一个函数延迟一秒后启动第二个函数(本例中的立方体),所以我试图延迟(time.sleep(1)) 在 "p1.start()" 和 "p2.start()" 之间,但它不起作用,两个函数仍然从 (0.000000s) 开始,然后我将延迟放在 "cube " 函数的开头而且它也没有用,所以我的问题是如何实现这两个功能之间的延迟?
在处理多线程时,各种其他因素都会影响您所看到的内容。由于您实际上是将子流程添加到 OS 的流程管理器中,它们将完全独立于您的 运行ning 程序运行,包括拥有自己的资源、调度优先级、管道等。
1.) 不。原因是每个子进程都有自己的输出缓冲区,它正在写入该缓冲区,该缓冲区被写回父进程。由于您启动了两个子进程,然后告诉父进程阻塞线程直到子进程 p1 完成,因此 p2 子进程在 p1 进程完成之前无法将其缓冲区写入父进程。这就是为什么尽管等待了 12 秒,p2 进程的输出仍然显示 0.7 秒。
2.) 很难确定为什么子进程需要 12 秒才能 运行 它的进程。这可能是您的代码中的某些内容,也可能是其他许多原因,例如一个完全不同的进程劫持了您的 CPU 一段时间。首先,如果您尝试衡量实际时间与进程花费在 CPU 上的时间,那么 time.clock 可能不是您要查找的内容。其他评论者正确地建议使用高性能计数器来准确跟踪时间,以确保您测量时间的方式没有任何奇怪之处。此外,在开始、运行宁和终止一个新进程时,总是有一定程度的开销,虽然肯定不值得 12 秒。确定这 12 秒是否是您可以控制的最佳方法是多次 运行 应用程序,看看总结果时间是否存在很大差异。如果有,则可能是与计算机相关的其他情况运行正在处理它。
3.) 我猜问题出在 time.clock 测量上。 time.clock 调用计算进程在 CPU 上花费了多少时间。由于您正在使用多个进程,因此 time.clock 在进程启动时重置为 0。它是相对时间,不是绝对时间,是相对于进程的生命周期而言的。如果您在进程或休眠线程之间跳转,time.clock 不一定会增加您对绝对时间测量的想法。您应该使用类似 time.time() 或更好的东西,一个高性能计数器来正确跟踪实时。