【问题标题】:Multiprocessing/Multithreading - does not improve speed - Python多处理/多线程 - 不会提高速度 - Python
【发布时间】:2014-11-06 19:15:34
【问题描述】:

我是多处理/多线程模块的新手,我正在尝试检查它是否可以提高我的程序的速度。问题是它返回了意外的值。我也尝试了threading.Thread 而不是multiprocessing.Process 并且发生了同样的问题 - 它比不使用另一个线程运行得慢。

在这个例子中我使用了多处理模块,但是当我尝试多线程时几乎相同(不同之处在于 cmets) 下面是打印两个函数顺序运行的时间和这些函数并行运行的时间的代码:

import time
from threading import Thread
from multiprocessing import Process
import MyFile

    class PerformanceTesting:

        def __init__(self):
            self.clss = MyFile.MyClass('A')
            self.p1 = Process(target=self.f1) # I've tried also t1 = Thread(target=f1)
            self.p2 = Process(target=self.f2) # I've tried also t2 = Thread(target=f2)

        def f1(self):
            results = self.clss.doSomething(arg,arg)
            print results

        def f2(self):
            results = self.clss.doSomething(arg,arg)
            print results

    if __name__ == "__main__":
        perf = PerformanceTesting()

        # ATTEMPT USING MULTIPROCESSING
        start = time.time()
        perf.p1.start()
        perf.f2()
        perf.p1.join()
        print time.time()-start

        # ATTEMPT WITHOUT USING MULTIPROCESSING
        start = time.time()
        perf.f1()
        perf.f2()
        print time.time()-start

你能告诉我是否可以提高这个例子的速度吗? 我做错了什么?

我有个想法:是不是因为分割成更多的进程或线程需要几秒钟,所以在必须在一秒钟内返回结果的情况下它无济于事?

【问题讨论】:

  • doSomething() 方法有什么作用?主要是 I/O(例如读写文件、网络等)还是 CPU(数字运算、数据操作等)?在 Python 下,线程更胜于前者,进程更胜于后者。
  • @Kevin CPU(用字符串操作),有区别吗?谢谢
  • doSomething() 所做的更重要的是,运行需要多长时间?如果函数在很短的时间内完成,那么引入子流程可能不会产生明显的影响,并且最终可能会变慢。
  • @user3371056 在 Python 中,线程无法加速 CPU 密集型操作,因为全局解释器锁会阻止多个线程同时运行。
  • 你当然可以试试。还有在 C# VM 上运行的 IronPython。请注意,Jython 和 IronPython 不支持 Python 3.x,您将无法使用任何非纯 Python 模块(例如 numpy 和 scipy)。

标签: python multithreading multiprocessing python-multiprocessing


【解决方案1】:

这里有几件事让我看不惯,至少对于您正在尝试做的事情:

perf.p1.start()
perf.f2()
perf.p1.join()

这会启动进程p1,然后执行f2,然后通过p1.join() 等待p1 完成。这似乎违背了多处理的目的-从您的帖子中我假设您认为在单独的线程上运行进程可以使其运行得更快-不幸的是,除非您在物理上获得更好的 CPU,否则情况永远不会如此。

多处理的关键在于您的代码可以触发线程的start 函数,然后在它完成之前忘记它,同时继续处理其他事情。重要的是,除非您开始将代码分成许多并行运行的不同部分,以便它们可以在单独的基础上非常快速地完成,否则在执行相同的代码。

在这种情况下你可以做的是:

perf.p1.start()
perf.p2.start()
... do some more code, after which something happens when these two finish.

这将直接进入代码的下一部分,而无需等待您的函数完成,这将阻止函数阻塞主线程。但是,您必须实现一个信号/槽系统才能在它们完成时实际触发一个动作。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    相关资源
    最近更新 更多