【问题标题】:is nogil safe when accessing cython extension type members访问 cython 扩展类型成员时 nogil 是安全的
【发布时间】:2021-07-07 00:27:03
【问题描述】:

来自a similar question's answer

您应该能够访问 [一个扩展类型的] cdef 成员 [在一个 nogil 块内]...并调用他们标记为 nog​​il 的 cdef 函数。

但是,cython documentation 不同意:

GIL释放后,任何涉及python对象的操作都必须先重新获取GIL。

我假设“python 对象”包括 cython 扩展类型。这让我认为下面的伪代码是不安全的,因为它包含了在没有 GIL 的情况下修改 python 对象引起的竞争条件:

def function(ExtensionType arg):
    with nogil:
        # long running task
        # modify arg's member

arg = ExtensionType()
function(arg)
# access arg's member

# (alternatively, accessing and modifying the member could be swapped, with the same issue)

我已将其扩展为实际代码以说明我的困惑:

cimport cytime

cdef class Tester:
    cdef int val

    def get_val(self):
        return self.val

    def set_val(self):
        print("1: GIL acquired by set_val")
        with nogil:
            cytime.sleep(0.1) # give me the GIL later, I'm not ready for it yet
            self.val = 1
        print("3: GIL reacquired by set_val")

t = Tester()
t.set_val()
print("2: val should be 0, but actually is: " + str(t.get_val()))

我预计程序的执行如下:1、2、3。但是,这是输出:

1: GIL acquired by set_val
3: GIL reacquired by set_val
2: val should be 0, but actually is: 1

谁能解释一下?谢谢。

【问题讨论】:

  • val 应该是 1 吧?因为那是你设置的。它是安全的(......我会给出一个答案,希望稍后能说明为什么......)。但我认为您真的对 GIL 的作用感到困惑

标签: cython


【解决方案1】:

在没有 GIL 的情况下访问/写入 self.val 很好。您不需要对 self 进行任何引用计数(因为您已经有了对它的引用,并且不需要另一个引用)并且您不需要对 val 进行任何引用计数,因为这是一个 C int。实际上,您可以在没有 GIL 的情况下对 cdef class 实例执行合理的操作(例如,访问 nogil cdef 方法)。

Cython 通常会阻止您在 nogil 块中执行需要 GIL 的操作(它并不完美,但通常相当彻底)。

请注意,如果您选择从多个线程访问.val,那么您很可能会遇到竞争情况,这完全是您自己的错。我所说的“安全”是指 Python 引用计数状态不会被破坏。


您似乎对 nogil 块的作用有很大的误解,并将其视为类似于协程的东西!?

当你发布 GIL 时发生的一切就是它允许 other 你已经运行的 Python 线程。正在处理set_val 的线程按逻辑顺序继续:它停止并等待一点,它设置值,它等待重新获取 GIL,它打印语句 3,它返回到全局范围,它打印声明-2。

【讨论】:

    【解决方案2】:

    作为猜测,cdef class 实例被引用,因此需要受 GIL 保护。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-16
      • 1970-01-01
      • 1970-01-01
      • 2013-05-26
      • 1970-01-01
      • 2021-01-03
      • 1970-01-01
      相关资源
      最近更新 更多