err*_*ynn 5 c++ python macros multithreading c-preprocessor
我有一些代码应该是一个线程安全的python/c ++ api.我现在用的是宏Py_BEGIN_ALLOW_THREADS和Py_END_ALLOW_THREADS,其扩展到创建节约线程状态,并创建一个锁.我在方法退出之前释放锁; 一旦在if语句范围内,一旦在方法范围内.
为什么这不编译?它会生成错误:error: _save was not declared in this scope在第二个Py_END_ALLOW_THREADS宏.
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;
}
Run Code Online (Sandbox Code Playgroud)
我也尝试将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;
}
Run Code Online (Sandbox Code Playgroud)
编辑:我知道第二个例子不做线程清理; 然而,它编译.
Edit2:
Py_BEGIN_ALLOW_THREADS扩展为{ PyThreadState *_save; _save = PyEval_SaveThread();
Py_END_ALLOW_THREADS扩展为PyEval_RestoreThread(_save); }
注意范围括号前置BEGIN和附加END.为什么宏观扩展的逻辑选择包括范围界定?
来自[Python.Docs]:初始化、终结和线程 - Py_BEGIN_ALLOW_THREADS(重点是我的):
该宏扩展为
{ PyThreadState *_save; _save = PyEval_SaveThread();. 请注意,它包含一个左大括号;它必须与以下Py_END_ALLOW_THREADS宏匹配。有关该宏的进一步讨论,请参阅上文。
所以,编译错误的答案很清楚:
预处理后,第二个Py_END_ALLOW_THREADS 生成无效代码(并且括起来是无关紧要的,因为在定义UBUNTU#if defined (UBUNTU)时它永远不会工作,而在未定义 UBUNTU 时它将始终工作):
上页还举例说明了这两个宏的常见用例:
Run Code Online (Sandbox Code Playgroud)PyThreadState *_save; _save = PyEval_SaveThread(); ... Do some blocking I/O operation ... PyEval_RestoreThread(_save);
为什么这样设计(包括范围界定)?像您一样使用时可能会失败,因为这可能会导致很难发现错误(您的示例非常简单,但在更复杂的代码段中,有许多分支需要同样多的Py_END_ALLOW_THREADS,想象一下错过一个意味着什么,或者调用两次)。
为了解决您的问题,您必须重新设计代码以:
| 归档时间: |
|
| 查看次数: |
291 次 |
| 最近记录: |