Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 可以从多个线程安全地访问静态阵列吗?_Multithreading_Delphi_Delphi Xe2 - Fatal编程技术网

Multithreading 可以从多个线程安全地访问静态阵列吗?

Multithreading 可以从多个线程安全地访问静态阵列吗?,multithreading,delphi,delphi-xe2,Multithreading,Delphi,Delphi Xe2,如果保证每个线程只读/写阵列的特定子集,那么多个线程可以在同一(静态)阵列上工作,而不必求助于关键部分,等等 编辑-这是针对非引用计数类型的数组及其记录/打包记录的特定情况 如果是,有什么注意事项吗 我的直觉是肯定的,但我的直觉有时可能是不可靠的信息来源。不,在某些情况下,这不可能是线程安全的 我至少看到两个原因 一,。它将取决于静态数组内容 如果您使用一些非引用计数的类型(如双精度、整数、字节、短字符串),在大多数情况下不会有任何问题(至少在数据为只读/只读的情况下) 但是,如果使用一些引用计

如果保证每个线程只读/写阵列的特定子集,那么多个线程可以在同一(静态)阵列上工作,而不必求助于关键部分,等等

编辑-这是针对非引用计数类型的数组及其记录/打包记录的特定情况

如果是,有什么注意事项吗


我的直觉是肯定的,但我的直觉有时可能是不可靠的信息来源。

不,在某些情况下,这不可能是线程安全的

我至少看到两个原因

一,。它将取决于静态数组内容

如果您使用一些非引用计数的类型(如
双精度、整数、字节、短字符串
),在大多数情况下不会有任何问题(至少在数据为只读/只读的情况下)

但是,如果使用一些引用计数类型(如
字符串、接口或嵌套的动态数组),则必须注意线程安全

即:

TMyType1: array[0..1] of integer; // thread-safe on reading
TMyType2: array[0..1] of string;  // may be confusing
附加说明:如果您的
字符串
实际上在静态数组的某些子部分之间共享,则可能会混淆引用计数。除非你为每一个调用
UniqueString()。对于
双精度
整数
的数组,不会出现此问题

二,。它将取决于访问并发性

读访问应该是线程安全的,即使对于引用计数类型也是如此,但并发写可能会令人困惑。对于
字符串
,在某些随机情况下可能会出现GPF问题,尤其是在多核CPU上

一些安全的实施可能是:

  • 使用关键部分(尽可能小,以减少开销)或其他保护结构
  • 确保使用写时拷贝或内容的每线程私有拷贝
  • 最新注意事项(不是关于安全,而是关于性能):由于CPU之间的缓存同步,在多个CPU之间共享阵列可能会导致性能下降。当您使用分离的阵列时,性能有时会更好,确保它们的L1缓存窗口不会在CPU之间共享
请注意,在客户端,这类问题可能是调试的噩梦:多线程并发问题可能随机发生,并且很难跟踪。越安全越好,除非您有明确且经验证的性能问题

附加说明:对于double的静态数组的特定情况,数组的子部分仅由一个线程访问,它是线程安全的。但在所有情况下,即使对于静态数组,也没有绝对的线程安全规则。一旦使用某些引用计数类型或指针,您可能会出现随机问题。

假设:

  • 您有一个数组实例(静态或动态),并且
  • 数组的元素是纯值类型(即不包含引用),并且
  • 每个线程在不相交的子数组上运行,并且
  • 当线程在阵列上操作时,系统中没有其他内容写入阵列

  • 有了这些条件,我相信您的数据结构和线程模式满足了这些条件,那么所有算法都是线程安全的。

    好的,我现在知道这意味着什么了。我会称之为固定尺寸,但你看。大小是否固定没有区别。数组是全局范围、局部范围还是类范围都没有区别。数组是堆分配的还是堆栈分配的没有区别。这只是一个连续的项目数组。不,我错了。我从来不知道这个用法。我猜它一定是在我学习Delphi添加动态数组时引入的,因为之前所有的数组都是静态的。在任何情况下,静态与否都没有区别。这很公平。正如您所说,在任何情况下,似乎没有一个明显的理由说明并发访问应该是一个问题,但有时会有一些模糊的微妙之处混淆了这些事情。有时候,双重肯定是件好事。@DavidHeffernan有区别,IMHO。静态数组是在读取时分配和复制的(当然,除非它们是通过引用传递的),而动态数组是引用计数的,并且具有写时复制模式,这可能会有所不同。它(或多或少)类似于
    shortstring/string
    使用模式。在所有情况下,在某些情况下,静态数组可能不是线程安全的:请参阅我的答案。@ArnaudBouchez这是对“在同一(静态)数组上”的一种相当奇怪的解释。我把它理解为数组的同一个实例。所以,这里没有复制。很好的一点-我应该明确数组类型。在这种情况下,元素是双倍的压缩记录(我认为这应该是安全的)。在我看来,这个答案是完全错误的。问题的重点是每个线程在不相交的子数组上运行。只有拥有每个子数组的线程才能对其进行操作。无论元素类型是什么,这都是线程安全的。@DavidHeffernan-这也是一个很好的观点。引用计数对象的数组仅包含指针,是吗?@J。。。对否:它们包含一个指向某些内容的指针,前面有一个引用计数!线程安全问题与引用计数处理有关。即使引用计数访问使用原子低级asm指令,在多个线程上,在并发更新的情况下,也可能存在一些竞争条件。对于阅读,它是可以的。@J。。。如果每个线程都在自己的私有子数组上运行,那么它对数组中的内容没有任何影响。好的,例外情况是,如果不同的子数组包含对公共对象的引用。如果对同一对象的引用保证只存在于单个子数组中(即:不相交的子数组之间没有共享的公共引用),我认为引用类型对象也会是这种情况。@J。。。是的,没错。只要每个线程对该线程私有的数据进行操作,那么algor