Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.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_Multiprocessing_Threadpool_Python Multiprocessing - Fatal编程技术网

Python 什么';线程池与多处理模块中的池之间的区别是什么?

Python 什么';线程池与多处理模块中的池之间的区别是什么?,python,python-3.x,multiprocessing,threadpool,python-multiprocessing,Python,Python 3.x,Multiprocessing,Threadpool,Python Multiprocessing,多处理模块中的ThreadPool和Pool有什么区别。当我尝试我的代码时,我看到的主要区别是: from multiprocessing import Pool import os, time print("hi outside of main()") def hello(x): print("inside hello()") print("Proccess id: ", os.getpid()) time.sleep(3) return x*x if _

多处理
模块中的
ThreadPool
Pool
有什么区别。当我尝试我的代码时,我看到的主要区别是:

from multiprocessing import Pool
import os, time

print("hi outside of main()")

def hello(x):
    print("inside hello()")
    print("Proccess id: ", os.getpid())
    time.sleep(3)
    return x*x

if __name__ == "__main__":
    p = Pool(5)
    pool_output = p.map(hello, range(3))

    print(pool_output)
我看到以下输出:

hi outside of main()
hi outside of main()
hi outside of main()
hi outside of main()
hi outside of main()
hi outside of main()
inside hello()
Proccess id:  13268
inside hello()
Proccess id:  11104
inside hello()
Proccess id:  13064
[0, 1, 4]
hi outside of main()
inside hello()
inside hello()
Proccess id:  15204
Proccess id:  15204
inside hello()
Proccess id:  15204
[0, 1, 4]
使用“线程池”:

我看到以下输出:

hi outside of main()
hi outside of main()
hi outside of main()
hi outside of main()
hi outside of main()
hi outside of main()
inside hello()
Proccess id:  13268
inside hello()
Proccess id:  11104
inside hello()
Proccess id:  13064
[0, 1, 4]
hi outside of main()
inside hello()
inside hello()
Proccess id:  15204
Proccess id:  15204
inside hello()
Proccess id:  15204
[0, 1, 4]
我的问题是:

  • 为什么每次都在
    池中运行“outside\uuuu main\uuuuuuuuuo()”

  • multiprocessing.pool.ThreadPool
    不会产生新进程吗?它只是创建新线程

  • 如果是这样,那么使用
    多处理.pool.ThreadPool
    与仅使用
    线程处理
    模块有什么区别


我在任何地方都没有看到任何关于
ThreadPool
的官方文档,有人能帮我找到它吗?

多处理.pool.ThreadPool的行为与
多处理.pool
相同,唯一的区别是使用线程而不是进程来运行worker逻辑

你看到的原因

hi outside of main()
使用
多处理.Pool
多次打印是因为该池将包含5个独立的进程。每个进程将初始化自己的Python解释器并加载模块,从而再次执行顶级的
print

请注意,只有在使用
spawn
进程创建方法(仅Windows上可用的方法)时才会发生这种情况。如果使用
fork
one(Unix),您将看到与线程一样只打印一次消息


multiprocessing.pool.ThreadPool
没有文档记录,因为它的实现从未完成。它缺乏测试和文档。您可以在中看到它的实现

我相信下一个自然的问题是:何时使用基于线程的池,何时使用基于进程的池

经验法则是:

  • IO绑定作业->
    多处理.pool.ThreadPool
  • CPU绑定作业->
    多处理.Pool
  • 混合作业->取决于工作负载,由于进程隔离带来的优势,我通常更喜欢
    多处理.Pool

在Python 3上,您可能想看看池实现。

我知道,由于Python中的GIL,Python的多线程看起来像多线程,但它不是真实的。如果希望利用python的多核功能,则需要使用多处理。在现代计算机中,创建一个进程和创建一个线程的成本几乎相同。创建一个线程的成本可能与创建一个进程的成本相似,但是线程之间的通信与进程之间的通信的成本非常不同(除非您使用共享内存)。此外,您对GIL的评论只有一部分是正确的:它是在I/O操作期间发布的,并且由一些库(例如numpy)发布,甚至是在CPU限制的操作期间。尽管如此,GIL仍然是在Python中使用单独进程的最终原因。@Yves这在*nix上可能是正确的,通过使用
fork
,但在Windows上不是正确的,并且没有考虑到进程与线程(在所有平台上)之间通信的额外开销、限制和复杂性。要回答有关
线程化
线程池
的问题,在
线程化
中,没有简单直接的方法获取辅助函数的返回值。然而,在
ThreadPool
中,您可以轻松获得辅助函数的返回值。谢谢您的回答。我只想理解这句话:请注意,只有在使用spawn进程创建方法时才会发生这种情况(只有在Windows上可用的方法)。如果您使用fork one(Unix),您将看到与线程一样只打印一次消息。我假设,当我调用“map()”或“Pool()”时,“spawn”和“fork”是隐式的?或者这是我可以控制的吗?我在上面提到start方法时给你的链接中有解释。您可以控制它,但启动方法的可用性取决于操作系统平台。我假设您使用的是Windows,因为默认的启动策略是
spawn
one。如果是这样,那就没什么可做的了,因为Windows只支持
spawn
。关于
ThreadPool
未完成的实现的评论在2019年Python 3.7版中仍然有效吗?是的。正如您从链接的源代码和缺乏文档中所看到的那样。@MrR,这是绝对合理和正确的,但这并没有真正说明为什么IO绑定作业更喜欢线程池而不是池(进程);尽管如此,我认为这是可以简单地用常识来解释的,它涉及到完成整个子流程所需的时间,以及由于不能共享相同的资源而导致的额外开销。