在没有同步的情况下多线程读取和写入预分配的动态数组
Reading and Writing to a pre-allocated dynamic array multi-threaded without synchronization
一般(Generic):
我们有一个动态数组 (Unreal Engine 4 TArray)。
我们在做任何工作之前预先分配它,并且在任何时候都不会修改它的大小。
当我们可以保证消费者读取的索引与生产者修改的索引不重叠时,从消费者线程读取数组是否安全,而生产者线程正在写入数组?
具体(详细):
我们有一个二维数组,由两个动态数组 (Unreal Engine 4 TArray) 实现。
外部数组 (X) 包含指向它的 uint8 类型的内部数组 (Y) 的指针,并预先分配了 NULL。它的大小永远不会改变。换句话说,我们有一个包含数组指针的数组,其中存储了实际数据。当生产者线程试图将数据写入此结构时,它只会以这种方式发生:数据被写入最新的现有(非 NULL)Y 数组。如果数据(部分)不再适合它,我们分配一个新的 Y 数组并预先分配它的最大大小(由我们设置为常量)。然后我们在下一个未使用的(NULL)索引处更新 X 数组中的指针以指向这个新的 Y 数组,并将剩余的数据写入其中。
消费者线程现在想从此结构中读取数据。这将保证不会出现在此时可能修改或尚不存在的任何索引上。由于生产者线程对时间要求很高(音频线程),我们希望尽可能保持无锁状态。在不实施同步的情况下,这是一个安全的程序吗?
在一个线程中写入并在另一个线程中读取时,您总是需要一些同步。没有同步你会得到未定义的行为。实际上,编译器可能会很好地注意到写入线程写入的数据未被读取。由于没有同步原语,它可以推断出它也没有被读取,并且优化代码以省略写入。
你 可能 将填充的数组移交给某种具有原子操作的队列,但这样做显然很重要,而且你不太可能得到如果你需要问你问的问题是对的:实现无锁队列需要对潜在的数据竞争有很好的理解(尽管它似乎是一个 producer/consumer 队列 can实现了无锁;就我个人而言,我仍然会远离它,因为我肯定做不到。
一般(Generic):
我们有一个动态数组 (Unreal Engine 4 TArray)。 我们在做任何工作之前预先分配它,并且在任何时候都不会修改它的大小。 当我们可以保证消费者读取的索引与生产者修改的索引不重叠时,从消费者线程读取数组是否安全,而生产者线程正在写入数组?
具体(详细):
我们有一个二维数组,由两个动态数组 (Unreal Engine 4 TArray) 实现。 外部数组 (X) 包含指向它的 uint8 类型的内部数组 (Y) 的指针,并预先分配了 NULL。它的大小永远不会改变。换句话说,我们有一个包含数组指针的数组,其中存储了实际数据。当生产者线程试图将数据写入此结构时,它只会以这种方式发生:数据被写入最新的现有(非 NULL)Y 数组。如果数据(部分)不再适合它,我们分配一个新的 Y 数组并预先分配它的最大大小(由我们设置为常量)。然后我们在下一个未使用的(NULL)索引处更新 X 数组中的指针以指向这个新的 Y 数组,并将剩余的数据写入其中。
消费者线程现在想从此结构中读取数据。这将保证不会出现在此时可能修改或尚不存在的任何索引上。由于生产者线程对时间要求很高(音频线程),我们希望尽可能保持无锁状态。在不实施同步的情况下,这是一个安全的程序吗?
在一个线程中写入并在另一个线程中读取时,您总是需要一些同步。没有同步你会得到未定义的行为。实际上,编译器可能会很好地注意到写入线程写入的数据未被读取。由于没有同步原语,它可以推断出它也没有被读取,并且优化代码以省略写入。
你 可能 将填充的数组移交给某种具有原子操作的队列,但这样做显然很重要,而且你不太可能得到如果你需要问你问的问题是对的:实现无锁队列需要对潜在的数据竞争有很好的理解(尽管它似乎是一个 producer/consumer 队列 can实现了无锁;就我个人而言,我仍然会远离它,因为我肯定做不到。