15

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

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.

4

2 回答 2

25

使用printf来自stdio

from libc.stdio cimport printf
...
printf("%f\n", c)
于 2018-01-21T03:52:09.730 回答
19

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

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

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

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

with gil:
    print c

它可能不会花费您太多的性能,并且可以节省大量的编程工作量。

于 2018-01-22T19:23:07.470 回答