python中的多线程:大部分时间它是否真的具有性能效率?

bra*_*orm 2 python multithreading multiprocessing gil

在我的小小理解中,multi-threading在大多数情况下驱动编程的性能因素并非全部.(不论Java或Python).

我读这启发性的文章GIL的SO.文章总结了python采用的GIL机制; 即只有一个single Thread可以python byte code在任何给定时间执行.这使得single thread应用程序真的更快.

我的问题如下:

因为如果Thread在给定点只提供一个,是否multiprocessingthread模块提供了克服GIL强加的限制的方法?如果没有,它们为实际multi-task工作提供了哪些功能

在接受的答案中,上述帖子的评论部分提出了一个问题,但没有回答?我脑子里也有这个问题

^so at any time point of time, only one thread will be serving content to client... 
so no point of actually using multithreading to improve performance. right?
Run Code Online (Sandbox Code Playgroud)

Jul*_*ard 10

你对GIL是正确的,没有必要使用多线程来进行CPU绑定计算,因为CPU只能由一个线程使用.

但是之前的陈述可能会启发你:如果你的计算不受CPU限制,你可以利用多线程.

一个典型的例子是当你的应用程序花费大部分时间等待某事时.

许多非CPU绑定程序的例子之一:假设您要构建一个Web爬虫,您必须抓取许多网站,并将它们存储在数据库中,成本倍数是多少?等待服务器发送数据,实际下载数据,并将其存储在数据库中,这里没有任何CPU绑定.在这里,您可以使用爬虫池而不是单个爬虫来获得更快的爬虫.通常情况下,一个网站几乎停机且响应速度很慢(~30秒),在此期间,单线程应用程序将等待网站,您就会被卡住.在多线程应用程序中,其他线程将继续爬行,这很酷.

另一方面,由于每个进程有一个GIL,您可以使用多处理来执行CPU绑定计算.

作为旁注,它存在一些或多或少部分没有GIL的Python部分实现,我想提一个我认为实现一些很酷的方法:pypy STM.你很容易找到,搜索"摆脱GIL"关于这个主题的很多线索.

  • 只是为了明确:I/O绑定操作实际上可以跨线程运行并发,因为Python将在任何类型的阻塞I/O操作运行时释放GIL.此规则的唯一例外是,如果编写得不好的C扩展在阻止I/O时无法释放GIL.在这种情况下,您将被困在运行I/O的线程中,直到I/O完成. (2认同)
  • @brainstorm“多处理”模块能够在进程之间共享对象,但这样做的成本比线程更高。在进程之间发送的对象需要进行 pickle,通过套接字发送到另一个进程,然后在另一端 unpickled。作为库的客户端,这对您来说几乎是不可见的,但它比单个进程中线程之间的共享状态要慢得多。还有一些其他共享状态的选项(与“ctypes”、“multiprocessing.Manager”共享内存),但这些选项也有一些缺点。 (2认同)