【问题标题】:Multiprocessing with Python Process使用 Python 进程进行多处理
【发布时间】:2018-08-23 16:35:14
【问题描述】:

我正在尝试使用“进程”将 Python 脚本修改为多进程。问题是它不起作用。在第一步中,按顺序检索内容(test1,test2)。在第二个中,它将被并行调用(test1 和 test2)。几乎没有速度差异。如果您单独执行这些功能,您会注意到不同之处。在我看来,并行化应该只需要最长的单个过程。我在这里错过了什么?

import multiprocessing
import time

def test1(k):
           k = k * k
           for e in  range(1, k):
                          e = e**k
def test2(k):
           k = k * k
           for e in  range(1, k):
                          e = e + 5 - 5*k ** 4000
if __name__ == '__main__':

           start = time.time()
           test1(100)
           test2(100)
           end = time.time()
           print(end-start)

           start = time.time()
           worker_1 = multiprocessing.Process(target=test1(100))
           worker_1.start()

           worker_2 = multiprocessing.Process(target=test2, args=(100,))
           worker_2.start()

           worker_1.join()
           worker_2.join()
           end = time.time()
           print(end-start)

我想补充一点,我检查了任务管理器,发现只使用了 1 个核心。 (4 个真正的核心仅 25% CPU => 1 个核心 100% 使用)

我知道 Pool Class,但我不想使用它。

感谢您的帮助。

更新

大家好, 带有“错字”的那个是不利的。对于那个很抱歉。 Bakuriu,谢谢你的回答。事实上,你是对的。我认为这是错字和太多的工作。 :-( 所以我再次更改了示例。对于所有感兴趣的人:

我创建了两个函数,在 main 的第一部分我依次运行了 3 次函数。我的电脑需要大约。 36 秒。然后我开始两个新进程。它们在这里并行计算它们的结果。作为一个小补充,程序本身的皮肤进程也计算了函数test1,这应该表明主程序本身也可以做一些事情。我得到 12 秒的计算时间。为了让互联网上的所有人都能理解,这是什么意思,我曾经在这里附上一张图片。 Task Manager

import multiprocessing
import time

def test1(k):
           k = k * k
           for e in  range(1, k):
                          e = e**k

def test2(k):
           k = k * k
           for e in  range(1, k):
                          e = e**k

if __name__ == '__main__':


           start = time.time()
           test1(100)
           test2(100)
           test1(100)
           end = time.time()
           print(end-start)


           start = time.time()
           worker_1 = multiprocessing.Process(target=test1, args=(100,))
           worker_1.start()

           worker_2 = multiprocessing.Process(target=test2, args=(100,))
           worker_2.start()

           test1(100)

           worker_1.join()
           worker_2.join()
           end = time.time()
           print(end-start)

【问题讨论】:

  • "我知道 Pool Class,但我不想使用它。"为什么?我认为您是连续启动进程并且每次只启动一个进程,因此没有理由让它更快。
  • @roganjosh 在我看来,多处理是 Python 的并行化包,带有 Pool 和 Process 类。两者都支持并行处理。或者那是错的?这是一个小例子。我的实际代码非常长,但它反映了问题。
  • 是的,但每个进程仍受global interpreter lock 的约束。如果您一次只启动一个进程来尝试执行繁重的 CPU 工作,那么您可能还只是坚持您正在运行的原始进程而不使用 multiprocessing。仅当您可以在多个并发进程之间划分工作时,它才有效。 multiprocessing.Process 不会比您已经在自己运行的原始进程更快地执行任何操作。
  • @roganjosh 感谢您的回答。现在我不确定我是否理解正确,我想用“进程”开始我自己的进程在另一个核心上运行?如果没有,我怎么去那里?
  • 确实如此,但您并没有指示当前进程执行任何操作。因此,您只需将工作转移到另一个运行与您已经在运行的进程完全相同的进程(如果它受 CPU 限制)。你说你不想使用池,我问为什么;你还没有回答。

标签: python process parallel-processing multiprocessing


【解决方案1】:

您的代码是按顺序执行的,因为您没有将test1 传递给Processtarget 参数,而是将test1结果 传递给它!

你想这样做:

worker_1 = multiprocessing.Process(target=test1, args=(100,))

正如你在另一个电话中所做的那样不是

worker_1 = multiprocessing.Process(target=test1(100))

此代码首先执行test1(100),然后返回None 并将其分配给target,从而产生一个“空进程”。之后,您生成第二个执行test2(100) 的进程。因此,您按顺序执行代码,加上产生两个进程的开销。

【讨论】:

  • 感谢您的回答,这至少解释了代码中的错误。不过,现在真正的问题仍然存在,我只使用了一个核心,而不是我想象的两个。
  • @Airfox 似乎test1 几乎占用了所有时间。我试图运行你的程序打印第一个和第二个任务顺序的时间,然后是并行版本的时间。数字是:第一个任务:8.730686902999878,第二个任务2.1878798008,两个任务并行8.73914003372。如您所见,并行版本 is 与最后结束的任务同时运行。不幸的是,该任务的持续时间方式比另一个要长,因此它不能很好地并行化
最近更新 更多