python - if 语句范围内的 C++ 宏未编译

标签 python c++ multithreading macros c-preprocessor

我有一些代码应该是线程安全的 python/c++ api。我正在使用宏 Py_BEGIN_ALLOW_THREADSPy_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); 请注意 BEGINEND 之前的作用域大括号。为什么包含范围界定的宏扩展是合乎逻辑的选择?

最佳答案

预处理器将宏 Py_BEGIN_ALLOW_THREADS 扩展为创建名为 _save 的本地对象的代码。

预处理器将宏 Py_END_ALLOW_THREADS 扩展为使用 _save 执行线程清理任务的代码。

如果将 Py_BEGIN_ALLOW_THREADS 放在 else block 中,则 Py_END_ALLOW_THREADS 创建的代码看不到本地 _save 对象,因此您得到一条错误消息。

在相关主题上,我建议放置 Py_BEGIN_ALLOW_THREADSPy_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/

相关文章:

c++ - 互斥体上的条件断点未触发

Javascript 扩展函数返回的内容?

python - `__init__` 能做什么而 `__new__` 不能?

c - windows内核编程中如何使用线程?

c++ - borland turbo c++ 4.5 中的 FMOD 错误

c++ - 你如何用特征向量制作矩阵?

c++ - 如何确定 Win32 线程是否已终止?

Python AlsaLib 错误

python - OOP/try except 类的 __init__ 中的语句

c++ - 如何运行示例 Armadillo 程序