python - 由于 GIL,多线程 Python 代码中是否不需要锁?

标签 python multithreading locking

如果您依赖具有全局解释器锁(即 CPython)的 Python 实现并编写多线程代码,那么您真的需要锁吗?

如果 GIL 不允许并行执行多条指令,难道共享数据就不需要保护了吗?

对不起,如果这是一个愚蠢的问题,但这是我一直想知道的关于多处理器/核心机器上的 Python 的问题。

同样的事情也适用于任何其他具有 GIL 的语言实现。

最佳答案

如果你在线程之间共享状态,你仍然需要锁。 GIL 只在内部保护解释器。您仍然可以在自己的代码中出现不一致的更新。

例如:

#!/usr/bin/env python
import threading

shared_balance = 0

class Deposit(threading.Thread):
    def run(self):
        for _ in xrange(1000000):
            global shared_balance
            balance = shared_balance
            balance += 100
            shared_balance = balance

class Withdraw(threading.Thread):
    def run(self):
        for _ in xrange(1000000):
            global shared_balance
            balance = shared_balance
            balance -= 100
            shared_balance = balance

threads = [Deposit(), Withdraw()]

for thread in threads:
    thread.start()

for thread in threads:
    thread.join()

print shared_balance

在这里,您的代码在读取共享状态 (balance = shared_balance) 和写回更改的结果 (shared_balance = balance) 之间可能会中断,从而导致更新丢失.结果是共享状态的随机值。

为了使更新保持一致,run 方法需要锁定 read-modify-write 部分(在循环内)周围的共享状态或具有 some way to detect when the shared state had changed since it was read .

关于python - 由于 GIL,多线程 Python 代码中是否不需要锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/105095/

相关文章:

multithreading - 如何告诉Hotspot JVM使用单处理器还是多处理器线程同步?

android - 使用 Kotlin 协程将 Java 线程处理消息转换为队列

python - Ubuntu 中的多个版本的 Python

python - 如何计算pandas数据框中某些条件的比率

python - 按任意键对元组列表进行排序

android - 运行一个线程几秒钟

python - 优雅地处理子进程关闭

java - Hazelcast - 将锁键与映射值关联以进行锁监控的策略/算法?

postgresql - postgres pg_try_advisory_lock 和限制问题

sql-server - 是否有 SQL Server 相当于 PostgreSQL "select * for update"而不打开游标