在python中,我定义了一个全局变量,它由不同的线程读取/递增.由于GIL,这会在不使用任何锁定机制的情况下导致问题吗?
我需要将threading应用程序转换为应用multiprocessing程序有多种原因(GIL,内存泄漏).幸运的是,线程非常孤立,只能通过Queue.Queues进行通信.这个原语也可用,multiprocessing所以一切看起来都很好.在我进入这个雷区之前,我想就即将出现的问题得到一些建议:
Queue?我需要提供一些__setstate__吗?put立即返回(比如threading Queues)吗?我想将我的sigle-thread应用程序分成多个工作线程.只有一个问题 - 这个动作的表现怎么样?如果GIL阻止python当时执行多个线程,我会获得任何利润吗?
另一点(从c/c ++的角度来看) - 因为我知道每个线程,无论如何,只能执行,所以在比python解释器更低的层次我有相同的限制.
简介:python线程在部分任务切换中是否具有"本机"线程的效率较低?
我正在开发一个项目,我的代码吞吐量非常重要,经过一些考虑,我选择使我的程序具有线程.
主线程和子线程都添加和删除两个共享字典.考虑到python中的锁定性能,我是否一直在寻找关于某些输入的互联网,这是一个缓慢的操作,等等.
所以我得到的是因为python实际上实际上根本没有线程(考虑到GIL只能在一个核心上运行)如果我需要在我的应用程序中获得高性能我是否有任何东西可以通过使其成为线程而不是处理IO ?
编辑
实际的问题是(经过深刻的评论后)
多线程在python中是否有意义,因为有GIL?
当我调用f2py包装函数时,Global Interpretter Lock(GIL)是否会被释放?
(我很高兴尝试自己发现,但我对numpy来源不太熟悉,知道从哪里开始寻找)......
为了澄清,对这个问题的一个好的答案要么帮助我知道在numpy来源中寻找a的位置,Py_BEGIN_ALLOW_THREADS 或者它只是让我知道GIL是否被释放(最好有一些证据).
我对这个问题背景的理解:
因此我的问题是:
GIL 将如何影响所请求网页的下载?制作并行网页请求会很好地利用 python 线程吗?因为下载网页是一个 I/O 操作,这是否意味着线程有用?
我会想象一个线程会发出一个请求 > 另一个线程会在某个时候获得控制权并发出自己的请求 > 另一个线程将获得控制权等等。然后数据将开始流入,但是如何处理呢?下载会中断吗?我想我缺乏对操作系统、python 解释器和操作系统的响应处理的低级理解。
我有一些想要尽快运行的 Cython 代码。我是否需要释放 GIL 才能执行此操作?
假设我的代码与此类似:
import numpy as np
# trivial definition just for illustration!
cdef double some_complicated_function(double x) nogil:
return x
cdef void func(double[:] input) nogil:
cdef double[:] array = np.zeros_like(input)
for i in range(array.shape[0]):
array[i] = some_complicated_function(input[i])
Run Code Online (Sandbox Code Playgroud)
我从np.zeros_like类似于以下内容的行中收到大量错误消息:
nogilcode.pyx:7:40: Calling gil-requiring function not allowed without gil
nogilcode.pyx:7:29: Accessing Python attribute not allowed without gil
nogilcode.pyx:7:27: Accessing Python global or builtin not allowed without gil
nogilcode.pyx:7:40: Constructing Python tuple not allowed without gil
nogilcode.pyx:7:41: Converting to …Run Code Online (Sandbox Code Playgroud) 我想从 python 调用一些 c 函数来提高代码的性能。但我无法在网上找到当我使用 ctypes 库调用 C 函数时 GIL 是否被释放。举个简单的例子:
from ctypes import *
fun = cdll.LoadLibrary("libc.so.6")
fun.sleep.argtypes = [c_uint]
fun.sleep(c_uint(5))
Run Code Online (Sandbox Code Playgroud)
GIL 是否在调用期间被释放fun.sleep?
我想知道,如果 python GIL 只允许一次运行一个线程/进程,为什么我应该使用 asyncio,我知道线程之间的切换很昂贵,但是就是这样?这是Python中asyncio的唯一优点吗?
如果所有 fastapi 端点都定义为async def,那么只会有 1 个线程在运行,对吗?(假设有一个独角兽工人)。
只是想确认在这样的设置中,我们永远不会遇到 python 的全局解释器锁。如果在一个具有多个线程的 Flask 框架中为单个 Gunicorn Worker 做同样的事情,那么我们将面临 GIL,它阻碍了线程之间真正的并行性。
所以基本上,在上面的 fastapi 中,并行度限制为 1,因为只有一个线程。为了利用所有核心,我们需要增加使用 Gunicorn 或 uvicorn 的工作人员数量。
我的理解正确吗?
gil ×10
python ×10
ctypes ×1
cython ×1
f2py ×1
fastapi ×1
fortran ×1
gunicorn ×1
httpresponse ×1
numpy ×1
performance ×1
python-cffi ×1
uvicorn ×1