问题描述
在Python C扩展中操纵GIL的最简单方法是使用提供的宏:
my_awesome_C_function()
{
blah;
Py_BEGIN_ALLOW_THREADS
//做一些不需要GIL的东西
if(should_i_call_back){
Py_BLOCK_THREADS
//做需要GIL的东西
Py_UNBLOCK_THREADS
}
Py_END_ALLOW_THREADS
return blah blah;
}
这很好,让我释放大部分代码的GIL,但重新获取它需要它的小部分代码。
问题是,当我用gcc编译这个时,我得到:
ext / engine.c:548:warning:'_save'可能在此函数中未初始化使用
$因为Py_BEGIN_ALLOW_THREADS是这样定义的:
#define Py_BEGIN_ALLOW_THREADS {pre
\
PyThreadState * _save; \
_save = PyEval_SaveThread();
所以,有三个问题:
- 是否可以抑制gcc的警告,
- 有没有人知道为什么gcc认为可以使用
_save
未初始化,因为它在声明后立即分配,并且
- 为什么宏定义不能在一个语句中声明和初始化变量以避免该问题?
>
(后两个确实只是为了我自己的好奇心)。
我可以避免这个问题,不要使用宏,而是自己做,但我宁愿不要。
解决方案
- 是的,可以使用-Wno-前缀来抑制未初始化的警告。
-Wall -Wno-uninitialized
如果您只想删除此警告,您可以简单地将
_save
初始化为空指针,以便它不依赖函数返回值...一行代码和一条评论对我来说很有意义:PyThreadState * _save;
_save = 0; / * init作为空指针值* /
_save = PyEval_SaveThread();
The simplest way to manipulate the GIL in Python C extensions is to use the macros provided:
my_awesome_C_function() { blah; Py_BEGIN_ALLOW_THREADS // do stuff that doesn't need the GIL if (should_i_call_back) { Py_BLOCK_THREADS // do stuff that needs the GIL Py_UNBLOCK_THREADS } Py_END_ALLOW_THREADS return blah blah; }
This works great, letting me release the GIL for the bulk of my code, but re-grabbing it for small bits of code that need it.
The problem is when I compile this with gcc, I get:
ext/engine.c:548: warning: '_save' might be used uninitialized in this function
because Py_BEGIN_ALLOW_THREADS is defined like this:
#define Py_BEGIN_ALLOW_THREADS { \ PyThreadState *_save; \ _save = PyEval_SaveThread();
So, three questions:
- Is it possible to suppress gcc's warning,
- Does anyone have any idea why gcc thinks
_save
might be used uninitialized, since it is assigned to immediately after its declaration, and- Why wouldn't the macro have been defined to declare and initialize the variable in one statement to avoid the issue?
(the last two are really just for my own curiosity).
I can avoid the issue by not using the macros and doing it all myself, but I'd rather not.
解决方案
- Yes, it is possible to suppress uninitialized warnings using the -Wno- prefix.
-Wall -Wno-uninitialized
If you want to remove just this warning, you could simply initialize
_save
to a null pointer so that it doesn't rely on a function return value... that one line of code and a comment makes sense to me:PyThreadState *_save; _save = 0; /* init as null pointer value */ _save = PyEval_SaveThread();
这篇关于如何在使用Py_BEGIN_ALLOW_THREADS时避免Python C扩展中的gcc警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!