我有一些代码应该是线程安全的 python/c++ api。我正在使用宏 Py_BEGIN_ALLOW_THREADS
和 Py_END_ALLOW_THREADS
,它们扩展以创建保存线程状态并创建锁。我在方法退出之前释放锁;一次在 if
语句范围内,一次在方法范围内。
为什么不能编译?它在第二个 Py_END_ALLOW_THREADS
宏中生成错误:error: _save was not declared in this scope
。
uint8_t SerialBuffer::push_msg() {
#if defined (UBUNTU)
Py_BEGIN_ALLOW_THREADS
#endif
if (_type == ARRAY) {
// array access
} else if (_type == PRIORITY_QUEUE) {
// queue access
} else {
// Placing the return statement in the preprocessor directive
// has no effect.
#if defined (UBUNTU)
Py_END_ALLOW_THREADS
#endif
return FAIL;
}
#if defined (UBUNTU)
Py_END_ALLOW_THREADS
#endif
return SUCCESS;
}
我还尝试将 return
语句放在 #if
指令范围内,这会产生相同的错误。但是,这有效:
uint8_t SerialBuffer::push_msg() {
#if defined (UBUNTU)
Py_BEGIN_ALLOW_THREADS
#endif
if (_type == ARRAY) {
// array access
} else if (_type == PRIORITY_QUEUE) {
// queue access
} else {
// NOTE lack of #if directive here.
// Even though if this code executes the code below will not.
// Seems like a relatively simple problem for lambda calculus, no?
return FAIL;
}
#if defined (UBUNTU)
Py_END_ALLOW_THREADS
#endif
return SUCCESS;
}
编辑:我知道第二个例子不做线程清理;但是,它会编译。
编辑2:
Py_BEGIN_ALLOW_THREADS
扩展为 { PyThreadState *_save; _save = PyEval_SaveThread();
Py_END_ALLOW_THREADS
扩展为 PyEval_RestoreThread(_save);
请注意 BEGIN
和 END
之前的作用域大括号。为什么包含范围界定的宏扩展是合乎逻辑的选择?
最佳答案
预处理器将宏 Py_BEGIN_ALLOW_THREADS
扩展为创建名为 _save
的本地对象的代码。
预处理器将宏 Py_END_ALLOW_THREADS
扩展为使用 _save
执行线程清理任务的代码。
如果将 Py_BEGIN_ALLOW_THREADS
放在 else block 中,则 Py_END_ALLOW_THREADS
创建的代码看不到本地 _save
对象,因此您得到一条错误消息。
在相关主题上,我建议放置 Py_BEGIN_ALLOW_THREADS
和 Py_END_ALLOW_THREADS
如果第一个执行,那么第二个也会执行。如果您有数组类型或优先级队列类型,您的第二个版本的函数将不会为 Py_END_ALLOW_THREADS
执行线程清理任务。
试试这个:
uint8_t SerialBuffer::push_msg() {
#if defined (UBUNTU)
Py_BEGIN_ALLOW_THREADS
#endif
uint8_t response = FAIL;
if (_type == ARRAY) {
// array access
response = SUCCESS;
} else if (_type == PRIORITY_QUEUE) {
// queue access
response = SUCCESS;
}
#if defined (UBUNTU)
Py_END_ALLOW_THREADS
#endif
return response;
}
在此版本中,默认响应为 FAIL,因此您甚至不需要最后的 else 部分。如果一切顺利,其他 if 语句只会将响应设置为 SUCCESS。
关于python - if 语句范围内的 C++ 宏未编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45340241/