【发布时间】:2017-06-19 18:25:27
【问题描述】:
我有一个从我的多线程 Python 应用程序调用的 C 扩展。我在 C 函数的某处使用了静态变量 i,稍后我有一些 i++ 语句可以从不同的 Python 线程运行(该变量仅在我的 C 代码中使用,但我不屈服到 Python)。
由于某种原因,到目前为止我还没有遇到任何比赛条件,但我想知道这是否只是运气......
我没有任何与线程相关的 C 代码(没有 Py_BEGIN_ALLOW_THREADS 或任何东西)。
我知道 GIL 只保证单个字节码指令是原子的和线程安全的,因此 Python 中的 i+=1 语句不是线程安全的。
但我不知道 C 扩展中的 i++ 指令。有什么帮助吗?
【问题讨论】:
-
“我知道 GIL 只保证单个字节码指令是原子的和线程安全的”——它甚至不保证这一点。不过,您在 C 中的
i++应该没问题;中间不能释放 GIL。 C 代码不会释放 GIL,除非它进行显式调用以让其他线程有机会运行(但要小心调用您无法控制的代码,这可能会为您执行该调用)。 -
哇,我现在更困惑了。我读到here 说单字节码指令是线程安全的......你是什么意思,除非明确告知,C 代码永远不会释放 GIL?就像,即使我放了
sleep或一些等待/IO 指令?一旦你输入 C 代码,它只是一个单一的原子执行? -
常见的误解,但不,它们不是线程安全的,最明显的是因为单个
BINARY_ADD或任何操作码可以解析为用 Python 编写的任意用户定义函数。您必须确保执行操作码不会导致调用其他 Python 代码,并且任何涉及的 C 代码都不会显式释放 GIL。
标签: c multithreading python-2.7 python-c-api cpython