【问题标题】:jruby concurrent pool threads mixing up when combined for resultjruby 并发池线程在组合结果时混合在一起
【发布时间】:2021-07-15 04:45:40
【问题描述】:

有一个索引为 [[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]], [1, [16900], ...]

情况并非总是如此,因此取决于结果出现的顺序。 如果例如索引1计算完成后索引0的计算完成,则idx 1缺失,或者错误。但是也出现了其他混淆结果的情况:idx 0 before idx 1,但是idx 0的结果是idx 1的结果。

?

看起来线程并没有真正分开。可以强制执行,还是有更聪明的方法来保持不道德?

【问题讨论】:

    标签: threadpool jruby


    【解决方案1】:

    我发现一个选项是同步线程,但这会使算法再次变慢,所以更好的解决方案是:

    如果剩余元组已经具有区分传入结果的结构,则结果不会混淆:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-29
      • 2013-11-20
      • 2021-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      相关资源
      最近更新 更多