问题描述
有一个索引为 [[0,n_0],[1,n_1],...,[n,n_n]] 的数组。对于每个 n_i,都会调用一个函数。在每个线程终止后,有必要按第一个组件对线程的结果进行重新排序。就我能找到的方法而言,我通过询问索引是否是例如索引来组织索引是硬编码的。 0,然后为硬编码索引 0 单独启动代码。到目前为止,这是一种可行的方法(即使代码看起来好像有人不了解循环的用途)。
rest = []
tpl.each do |idx,vn|
if idx == 0
pool.post do
res = funk(vn)
p ['idx 0: ',res]
rest += [[0,res]]
end#pool.post
elsif idx == 1
pool.post do
res = funk(vn)
p ['idx 1: ',res]
rest += [[1,res]]
end#pool.post
end;end
但是现在有一个奇怪的行为: 索引 0 和 1 计算准确,但是当 1 的结果在后一行添加时,前一个函数的结果会被添加(再次)。
["idx 1: ",[4]]
["idx 0: ",[16900]]
rest: [[0,[16900]],[16900],...]
情况并非总是如此,因此这取决于结果出现的顺序。 如果例如索引0的计算在索引1的计算完成后,则idx 1缺失,或者错误。但也出现了其他混淆结果的情况:idx 0 在 idx 1 之前,但 idx 0 的结果是 idx 1 的结果。
?
看起来线程并没有真正分开。可以强制执行吗,或者有更聪明的方法来保持 indeces?
解决方法
我发现一种选择是同步线程,但这会使算法再次变慢,因此更好的解决方案是:
结果不会混淆,如果其余元组已经具有区分传入结果的结构:
rest = [[],[]]
tpl.each do |idx,vn|
if idx == 0
pool.post do
res = funk(vn)
p ['idx 0: ',res]
rest[0] << [0,res]
end#pool.post
elsif idx == 1
pool.post do
res = funk(vn)
p ['idx 1: ',res]
rest[1] << [1,res]
end#pool.post
end;end