Cython:如何在没有 GIL 的情况下进行打印

Cython: How to print without GIL

我应该如何在没有 gil 的 Cython 函数中使用 print?例如:

from libc.math cimport log, fabs
cpdef double f(double a, double b) nogil:
    cdef double c = log( fabs(a - b) )
    print c
    return c

编译时报错:

Error compiling Cython file:
...
    print c
    ^
------------------------------------------------------------

Python print statement not allowed without gil
...

我知道如何使用 C 库而不是它们的 python 等价物(例如此处的 math 库),但我找不到 print 的类似方法。

使用 printf 来自 stdio:

from libc.stdio cimport printf
...
printf("%f\n", c)

这是对评论中讨论的跟进,该讨论表明这个问题是基于一个轻微的误解:始终值得考虑为什么需要发布 GIL 以及是否真的需要这样做。

从根本上说,GIL 是每个线程持有的标志,用于指示是否允许调用 Python API。简单地持有旗帜不会花费你任何性能。 Cython 通常在不使用 Python API 时最快,但这是因为它正在执行的操作类型而不是因为它持有标志(即 printf 可能比Python print,但 printf 运行 使用或不使用 GIL 的速度相同)。

你唯一真正需要担心 GIL 的时候是在使用多线程代码时,释放它会给其他 Python 个线程 运行 机会。 (类似地,如果你正在编写一个库并且你不需要 Python API 发布 GIL 可能是个好主意,这样你的用户可以 运行 其他线程,如果他们想要的话).

最后,如果您在 nogil 块中并且想要快速执行 Python 操作,您可以简单地执行以下操作:

with gil:
    print c

很有可能它不会消耗太多性能,而且可以节省大量编程工作。