Cython: How to print without GIL

2019-05-08 06:35发布

How should I use print in a Cython function with no gil? For example:

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

gives this error when compiling:

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

Python print statement not allowed without gil
...

I know how to use C libraries instead of their python equivalent (math library for example here) but I couldn't find a similar way for print.

2条回答
仙女界的扛把子
2楼-- · 2019-05-08 06:56

Use printf from stdio:

from libc.stdio cimport printf
...
printf("%f\n", c)
查看更多
走好不送
3楼-- · 2019-05-08 07:15

This is a follow-up to a discussion in the comments which suggested that this question was based on a slight misconception: it's always worth thinking about why you need to release the GIL and whether you actually need to do it.

Fundamentally the GIL is a flag that each thread holds to indicate whether it is allowed to call the Python API. Simply holding the flag doesn't cost you any performance. Cython is generally fastest when not using the Python API, but this is because of the sort of operations it is performing rather than because it holds the flag (i.e. printf is probably slightly faster than Python print, but printf runs the same speed with or without the GIL).

The only time you really need to worry about the GIL is when using multithreaded code, where releasing it gives other Python threads the opportunity to run. (Similarly, if you're writing a library and you don't need the Python API it's probably a good idea to release the GIL so your users can run other threads if they want).

Finally, if you are in a nogil block and you want to do a quick Python operation you can simply do:

with gil:
    print c

The chances are it won't cost you much performance and it may save a lot of programming effort.

查看更多
登录 后发表回答