python queue是线程安全的吗_Python中的deque是线程安全的吗?

Python的deque在CPython实现中由于GIL的存在,使得append等操作是线程安全的。GIL保证了只有持有锁的线程能操作Python对象。尽管如此,在某些场景下,由于线程切换,仍需要在代码中添加锁来确保并发安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、首先第一个问题, deque源码里没有用锁保护critical section,是如何实现线程安全的?

看上去没有锁,但实际上是有的,没错就是GIL。

我们看Python文档中的解释the rule exists that only the thread that has acquired the GIL may operate on Python objects or call Python/C API functions. In order to emulate concurrency of execution, the interpreter regularly tries to switch threads (see sys.setcheckinterval()). The lock is also released around potentially blocking I/O operations like reading or writing a file, so that other Python threads can run in the meantime.

这段话的主要信息有:

1. 只有获取了GIL锁的线程才能操作Python对象或调用Python/C API

2. 什么时候会当前线程会释放GIL呢?一个是python解释器每执行若干条python指令(缺省值100)后会尝试做线程切换,让其他线程有机会执行。另一个是进行IO操作时,会释放掉GIL,当前线程进入睡眠。

那么deque的C语言实现中,以pop为例(deque_append_internal这个函数内容就不贴了)

static PyObject *

deque_append(dequeobject *deque, PyObject *item)

{

Py_INCREF(item);

if (deque_append_internal(deque, item, deque->maxlen) < 0)

return NULL;

Py_RETURN_NONE;

}

在通过Python/C API调用这个函数时,当前线程肯定是先拿到了GIL的,而在这个函数内部,没有主动释放GIL(如何释放,参考Initialization, Finalization, and Threads)所以整个函数可以看作被GIL保护的critical section。

第二个问题,既然有GIL,那为啥在很多时候我们写的代码还要加锁?

因为——再重复一次上面提到的——python解释器每执行若干条python指令(缺省值100)后会尝试做线程切换(释放GIL)。注意跟上面用Python/C API实现的函数不同,C函数中如果没有主动释放GIL,是不会有机会切走的。

结论:The deque's append(), appendleft(), pop(), popleft(), and len(d) operations are thread-safe in CPython

参考阅读:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值