移除 gil 并使用内存视图时,会出现此错误:
Fatal Python error: PyThreadState_Get: no current thread
同一个对象以前作为内存视图工作得很好。有关更多详细信息,请参见下面的代码。
# @boundscheck(False)
# @wraparound(False)
# @nonecheck(False)
cpdef c_calculated_mutation(
np.ndarray[int, ndim=3] population,
long mutations,
long[:] depotmap,
double[:,:] mapping,
np.ndarray[long, ndim=1] loads,
dict max_loads,
np.ndarray[long, ndim=1] durations,
dict max_durations
):
cdef:
int[:,:,:] pop = population
int xLen = len(population[0][0])
int yLen = len(population[0])
int zLen = len(population)
list export_changes = []
int x, y, z, xx, yy, i, max_depot, prev, value, mutation
float new_fitness, best
int[:,:] view
int* load_limits = <int*>malloc(len(max_loads) * sizeof(int))
int* duration_limits = <int*>malloc(len(max_durations) * sizeof(int))
int* fxes = <int*>calloc(mutations, sizeof(int))
int* fyes = <int*>calloc(mutations, sizeof(int))
int* txes = <int*>calloc(mutations, sizeof(int))
int* tyes = <int*>calloc(mutations, sizeof(int))
int* zes = <int*>calloc(mutations, sizeof(int))
int* xxx = <int*>calloc(mutations, sizeof(int))
int* yyy = <int*>calloc(mutations, sizeof(int))
int* zzz = <int*>calloc(mutations, sizeof(int))
i=0
for value in max_loads:
load_limits[i] = int(max_loads[value])
duration_limits[i] = int(max_durations[value])
max_depot = value
i += 1
for mutation in prange(mutations, nogil=True):
z = rand() % zLen
y = rand() % yLen
x = rand() % xLen
value = population[z, y, x]
while value >= 0:
x = rand() % xLen
value = population[z, y, x]
xxx[mutation] = x
yyy[mutation] = y
zzz[mutation] = z
这就是设置。该错误来自带有 gil 注释的 # 行。如果我使用 gil,程序会变慢很多。此外,在另一个函数中使用相同的对象作为内存视图也可以很好地工作。我不明白这一点。
for mutation in prange(mutations, nogil=True, num_threads=8):
x = xxx[mutation]
y = yyy[mutation]
z = zzz[mutation]
value = population[z, y, x]
xx = x
# with gil:
best = fitness(pop[z,:,:], xLen, yLen, depotmap, max_depot, mapping, loads, load_limits, durations, duration_limits)
for yy in range(yLen):
prev = population[z, yy, xx]
population[z, yy, xx] = value
population[z, y, x ] = prev
# with gil:
new_fitness = fitness(pop[z, :, :], xLen, yLen, depotmap, max_depot, mapping, loads, load_limits, durations, duration_limits)
if best > new_fitness:
best = new_fitness
fxes[mutation] = x
fyes[mutation] = y
txes[mutation] = xx
tyes[mutation] = yy
zes[mutation] = z
population[z, y, x ] = value
population[z, yy, xx] = prev
然后是其余的功能。
for mutation in range(mutations):
x = fxes[mutation]
y = fyes[mutation]
xx = txes[mutation]
yy = tyes[mutation]
z = zes[mutation]
export_changes += [z]
prev = population[z, yy, xx]
population[z, yy, xx] = population[z, y, x]
population[z, y, x ] = prev
free(load_limits)
free(duration_limits)
free(fxes)
free(fyes)
free(txes)
free(tyes)
free(zes)
free(xxx)
free(yyy)
free(zzz)
return population, export_changes