在线程之间共享数组是否安全? [英] Is it safe, to share an array between threads?

查看:89
本文介绍了在线程之间共享数组是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

像在下面的代码中那样在承诺之间共享数组是否安全?

Is it safe, to share an array between promises like I did it in the following code?

#!/usr/bin/env perl6
use v6;

sub my_sub ( $string, $len ) {
    my ( $s, $l );
    if $string.chars > $len {
        $s = $string.substr( 0, $len );
        $l = $len;
    }
    else {
        $s = $string;
        $l = $s.chars;
    }
    return $s, $l;
}

my @orig = <length substring character subroutine control elements now promise>;
my $len = 7;
my @copy;
my @length;
my $cores = 4;
my $p = @orig.elems div $cores;
my @vb = ( 0..^$cores ).map: { [ $p * $_, $p * ( $_ + 1 ) ] };
@vb[@vb.end][1] = @orig.elems;

my @promise;
for @vb -> $r {
    @promise.push: start {
        for $r[0]..^$r[1] -> $i {
            ( @copy[$i], @length[$i] ) = my_sub( @orig[$i], $len );
        }
    };
}
await @promise;


推荐答案

这取决于您如何定义数组和共享 。就数组而言,有两种情况需要分别考虑:

It depends how you define "array" and "share". So far as array goes, there are two cases that need to be considered separately:


  • 固定大小的数组(声明为我的@a [$ size] );这包括具有固定尺寸的多维数组(例如 my @a [$ xs,$ ys] )。它们具有有趣的特性,即不必调整支持它们的内存。

  • 动态数组(声明为 my @a ),按需增长。随着时间的推移,它们实际上会随着时间的推移使用大量内存。

  • Fixed size arrays (declared my @a[$size]); this includes multi-dimensional arrays with fixed dimensions (such as my @a[$xs, $ys]). These have the interesting property that the memory backing them never has to be resized.
  • Dynamic arrays (declared my @a), which grow on demand. These are, under the hood, actually using a number of chunks of memory over time as they grow.

就共享而言,还有三种情况:

So far as sharing goes, there are also three cases:


  • 这种情况是多个线程在其生命周期内接触数组,但只有一个线程可以在数组中接触它。时间,由于某种并发控制机制或整体程序结构。在这种情况下,从不使用使用数组的并发操作的意义共享数组,因此不可能发生数据争用。

  • 只读的,非延迟的情况。这是多个并发操作访问一个非延迟数组,但只能读取它的地方。

  • 读/写情况(包括由于数组已分配了某些东西而实际导致写操作的情况)

然后我们可以总结一下:安全性如下:

Then we can summarize the safety as follows:

                     | Fixed size     | Variable size |
---------------------+----------------+---------------+
Read-only, non-lazy  | Safe           | Safe          |
Read/write or lazy   | Safe *         | Not safe      |

*表示警告,尽管从Perl 6的角度来看是安全的,但您当然必须确保您没有在使用相同索引的情况下发生冲突。

The * indicating the caveat that while it's safe from Perl 6's point of view, you of course have to make sure you're not doing conflicting things with the same indices.

因此,总而言之,固定大小的数组可以安全地共享并分配给来自不同线程的元素。问题(但要注意虚假共享,这样做可能会给您带来沉重的性能损失)。对于动态数组,只有在共享期间才从中读取它们,即使它们不是很懒惰,它也是安全的(尽管给定的数组分配很急切,您不太可能遇到这种情况意外地)。由于操作不断增加,即使写入不同的元素,也可能会导致数据丢失,崩溃或其他不良行为的风险。

So in summary, fixed size arrays you can safely share and assign to elements of from different threads "no problem" (but beware false sharing, which might make you pay a heavy performance penalty for doing so). For dynamic arrays, it is only safe if they will only be read from during the period they are being shared, and even then if they're not lazy (though given array assignment is mostly eager, you're not likely to hit that situation by accident). Writing, even to different elements, risks data loss, crashes, or other bad behavior due to the growing operation.

因此,考虑原始示例,我们看到 my @copy; my @length; 是动态数组,因此我们不能在并发操作中写入它们。

So, considering the original example, we see my @copy; and my @length; are dynamic arrays, so we must not write to them in concurrent operations. However, that happens, so the code can be determined not safe.

这里已经有其他帖子做了很好的工作,指出了更好的方向,但没有人详细说明这些细节。

The other posts already here do a decent job of pointing in better directions, but none nailed the gory details.

这篇关于在线程之间共享数组是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆