Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为多处理脚本计时_Python_Python 3.x_Time_Python Multiprocessing - Fatal编程技术网

Python 为多处理脚本计时

Python 为多处理脚本计时,python,python-3.x,time,python-multiprocessing,Python,Python 3.x,Time,Python Multiprocessing,在使用多处理模块时,我偶然发现了一个奇怪的计时问题 考虑以下场景。我有这样的功能: import multiprocessing as mp def workerfunc(x): # timehook 3 # something with x # timehook 4 def outer(): # do something mygen = ... (some generator expression) pool = mp.Pool(pro

在使用多处理模块时,我偶然发现了一个奇怪的计时问题

考虑以下场景。我有这样的功能:

import multiprocessing as mp

def workerfunc(x):
    # timehook 3
    # something with x
    # timehook 4

def outer():

    # do something

    mygen = ... (some generator expression)

    pool = mp.Pool(processes=8)

    # time hook 1
    result = [pool.apply(workerfunc, args=(x,)) for x in mygen]
    # time hook 2

if __name__ == '__main__':
    outer()
我利用时间模块来获得函数运行时间的任意感觉。我成功地创建了8个独立的进程,这些进程在没有错误的情况下终止。工人完成工作的最长时间约为130毫秒(在时间钩3和4之间测量)

我预计(因为它们是并行运行的),钩子1和钩子2之间的时间将大致相同。令人惊讶的是,结果我得到了600毫秒

我的机器有32个内核,应该能够轻松处理。谁能给我一个提示,时间上的差异是从哪里来的


谢谢

因为您使用的是多处理而不是多线程,所以性能问题与GIL(Python的全局解释器锁)无关

我发现了一个有趣的链接,用一个例子解释了这一点,你可以在这个答案的底部找到它

GIL不会阻止进程在不同的服务器上运行 机器的处理器。它只允许一个线程同时运行 一次在口译员内

因此,多处理而非多线程将允许您实现真正的 并发性

让我们通过一些基准测试来理解这一点,因为 会让你相信上面说的话。是的,应该是这样 学习的方法 — 体验它,而不仅仅是阅读或阅读 理解它。因为如果你经历了什么,没有多少 争论可以说服你接受相反的想法

其他信息


您可以找到此信息的来源和更详细的技术解释(另外:其中还引用了Guido Van Rossum:)

因为您使用的是多处理而不是多线程,所以性能问题与GIL(Python的全局解释器锁)无关

我发现了一个有趣的链接,用一个例子解释了这一点,你可以在这个答案的底部找到它

GIL不会阻止进程在不同的服务器上运行 机器的处理器。它只允许一个线程同时运行 一次在口译员内

因此,多处理而非多线程将允许您实现真正的 并发性

让我们通过一些基准测试来理解这一点,因为 会让你相信上面说的话。是的,应该是这样 学习的方法 — 体验它,而不仅仅是阅读或阅读 理解它。因为如果你经历了什么,没有多少 争论可以说服你接受相反的想法

其他信息


您可以找到此信息的来源和更详细的技术说明(另外:其中还有Guido Van Rossum的引号:)

您使用的是
池。应用
,这是一种阻塞。使用
pool.apply_async
,然后所有函数调用都将并行运行,并且每个调用都将立即返回一个对象。您可以使用此对象检查进程何时完成,然后也可以使用此对象检索结果。

您使用的是
池。应用
,这是阻塞。使用
pool.apply_async
,然后所有函数调用都将并行运行,并且每个调用都将立即返回一个对象。您可以使用此对象检查流程何时完成,然后使用此对象检索结果。

这取决于您有多少任务。您有8个流程,这意味着您可以同时执行8项任务。但是如果你有8项以上的任务,很明显你需要更多的时间,对吗?例如,如果您有9个任务,那么使用8个进程将花费双倍的时间,因为一个任务需要。@Sraw:没错,但我正好有8个任务要运行。我操作8个DataFrame对象,并将的结果写入一个数组(在上面的示例中为结果)。这取决于您有多少任务。您有8个流程,这意味着您可以同时执行8项任务。但是如果你有8项以上的任务,很明显你需要更多的时间,对吗?例如,如果您有9个任务,那么使用8个进程将花费双倍的时间,因为一个任务需要。@Sraw:没错,但我正好有8个任务要运行。我操作8个pandas DataFrame对象并将的结果写入一个数组(上面的示例中的结果)。感谢您的回答,我知道GIL。正因为如此,我认为使用进程而不是线程将是一条出路。我错过什么了吗?说得好,@docdrive!我提供的第一个链接中有一个示例,它使用时间检查执行时间并比较多处理/多线程。也许这有助于检查代码中是否也可以实现更改。例如,他使用的是过程而不是池。谢谢你的回答,我知道GIL。正因为如此,我认为使用进程而不是线程将是一条出路。我错过什么了吗?说得好,@docdrive!我提供的第一个链接中有一个示例,它使用时间检查执行时间并比较多处理/多线程。也许这有助于检查代码中是否也可以实现更改。例如,他使用的是过程而不是池。谢谢,这将过程加速到可接受的水平。但我仍然有点困惑,这些过程是如何相互阻碍的。请您再解释一下,好吗?“Pool.apply与Python apply类似,只是函数调用是在一个单独的进程中执行的。Pool.apply会一直阻塞直到函数完成。”这里的完整帖子:好的,当您调用apply时,主进程会说您去做这项工作,我会在这里等您完成。Apply async说你去做这项工作,给我一张索赔单,我会回来取结果。谢谢,这将把过程加快到可接受的水平。但我还是有点合作
import random
from threading import Thread
from multiprocessing import Process
size = 10000000   # Number of random numbers to add to list
threads = 2 # Number of threads to create
my_list = []
for i in xrange(0,threads):
    my_list.append([])
def func(count, mylist):
    for i in range(count):
        mylist.append(random.random())
def multithreaded():
    jobs = []
    for i in xrange(0, threads):
        thread = Thread(target=func,args=(size,my_list[i]))
        jobs.append(thread)
    # Start the threads
    for j in jobs:
        j.start() 
    # Ensure all of the threads have finished
    for j in jobs:
        j.join()

def simple():
    for i in xrange(0, threads):
        func(size,my_list[i])

def multiprocessed():
    processes = []
    for i in xrange(0, threads):
        p = Process(target=func,args=(size,my_list[i]))
        processes.append(p)
    # Start the processes
    for p in processes:
        p.start()
    # Ensure all processes have finished execution
    for p in processes:
        p.join()
if __name__ == "__main__":
    multithreaded()
    #simple()
    #multiprocessed()