当前位置: 首页 > 面试题库 >

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

段阳夏
2023-03-14
问题内容

如果您依赖具有全局解释器锁(即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)之间中断,从而导致更新丢失。结果是共享状态的随机值。

为了使更新一致,运行方法将需要将共享状态锁定在read-modify-
write部分周围(循环内部),或者需要某种方法来检测共享状态自被读取以来何时发生了变化。



 类似资料:
  • 问题内容: class mythread implements Runnable { 输出为: 但是我想要的输出就像首先应该在线程“ rohan”中打印5,然后在“ jain”中打印5,然后在线程“ main”中打印5,依此类推…请帮助.. !!!!!! 问题答案: 这些问题确实使我感到困惑。线程的全部要点是它们并行 异步 运行,因此我们可以获得更好的性能。由于硬件,竞争条件,时间分段随机性和其他

  • 问题内容: 我只是想知道我们是否真的需要算法是多线程的,如果它必须利用多核处理器,或者jvm是否要利用多核处理器,即使我们的算法是顺序的? 问题答案: 我不相信任何当前的生产JVM实现都可以执行自动多线程。他们可能会使用其他核心进行垃圾回收和其他内部管理,但是如果您的代码是顺序表达的,则很难自动并行化它并仍然保留精确的语义。 有 可能 是一些实验/研究的JVM其中设法并行的代码的JIT可以当场为尴

  • 喷雾布线基于Akka actor系统。在我记得的所有示例代码中,路由都是“快速”完成的,并且将实际工作派生给其他参与者,除非需要同步完成以获得响应。 换句话说,喷雾路由多线程模型到底是什么? 我可以将验证生成给另一个参与者,但在这种情况下,REST API响应将不再能够报告传入内容是否存在错误。处理这件事的最佳方法是什么?

  • 问题内容: 我需要从该站点下载哪个tar? 我已经尝试过fortrans,但是一直出现此错误(明显地设置了环境变量之后)。 问题答案: 该SciPy的网页用来提供构建和安装说明,但说明现在依靠操作系统二进制分发。要在没有预编译所需库软件包的操作系统上构建SciPy(和NumPy),必须先构建然后静态链接到Fortran库BLAS和LAPACK: 仅执行五个g77 / gfortran / ifor

  • 问题内容: 该代码实际上是从Java并发中获取的,根据作者的说法,这里发生了“ ThreadStarvtionDeadlock”。请帮我找到ThreadStarvationDeadlock在这里和哪里发生的情况吗?提前致谢。 问题答案: 死锁和饥饿发生在以下行: 怎么样? 如果我们在程序中添加一些额外的代码,它将发生。可能是这样的: 导致死锁的步骤: 通过实现的类将任务提交给渲染页面。 开始在单独

  • 问题内容: 我想在我的JavaScript代码中包含几个JSON文件,这些文件与JavaScript源文件位于同一目录中。 如果我想包含另一个JavaScript文件,可以直接使用。现在,我正在使用和获取JSON,我认为这是执行此操作的丑陋方法。 是否有类似的要求,使我能够加载JSON文件? 问题答案: 从节点v0.5.x开始,是的,您可以像需要js文件一样要求JSON。 在ES6中: