【发布时间】:2017-02-09 18:44:20
【问题描述】:
我正在使用 prange 对这样的列表进行迭代:
from cython.parallel import prange, threadid
cdef int tid
cdef CythonElement tEl
cdef int a, b, c
# elList: python list of CythonElement instances is passed via function call
for n in prange(nElements, schedule='dynamic', nogil=True):
with gil:
tEl = elList[n]
tid = threadid()
a = tEl.a
b = tEl.b
c = tEl.c
print("thread {:} elnumber {:}".format(tid, tEl.elNumber))
#nothing is done here
with gil:
print("thread {:} elnumber {:}".format(tid, tEl.elNumber))
# some other computations based on a, b and c here ...
我希望得到这样的输出:
thread 0 elnumber 1
thread 1 elnumber 2
thread 2 elnumber 3
thread 3 elnumber 4
thread 0 elnumber 1
thread 1 elnumber 2
thread 2 elnumber 3
thread 3 elnumber 4
但我明白了:
thread 1 elnumber 1
thread 0 elnumber 3
thread 3 elnumber 2
thread 2 elnumber 4
thread 3 elnumber 4
thread 1 elnumber 2
thread 0 elnumber 4
thread 2 elnumber 4
那么,线程局部变量 tEl 不知何故被线程覆盖了?我究竟做错了什么 ?谢谢!
【问题讨论】:
-
你是对的。它似乎没有使
tEl线程本地化(查看生成的 C 文件,并搜索lastprivate进行检查)。如果将其更改为基本类型(如double),它可以工作,但似乎不适用于 Cython 对象类型。我不知道一个明显的解决方案,但可能值得在 github 上提交一个错误
标签: multithreading parallel-processing cython