我有一个二维数组和 8 个并发线程写入该数组。如果每个线程读取/写入不同的数组,会导致段错误吗?
例如:
char **buffer;
//each thread has its own thread ID
void set(short ID, short elem, char var)
{
buffer[ID][elem] = var;
}
这样可以吗?我知道这是伪代码,但你明白了。
我有一个二维数组和 8 个并发线程写入该数组。如果每个线程读取/写入不同的数组,会导致段错误吗?
例如:
char **buffer;
//each thread has its own thread ID
void set(short ID, short elem, char var)
{
buffer[ID][elem] = var;
}
这样可以吗?我知道这是伪代码,但你明白了。
如果每个线程写入不同的子数组,您的代码的这方面会很好,您将不需要锁定。
多个线程读取或写入内存本身不会导致段错误。它可以做的是导致竞争条件,其中结果不确定地取决于多个线程的操作顺序。结果取决于您对读取的内存所做的操作...如果您读取一个值然后将其用作索引或取消引用指针,即使运行代码的逻辑也可能导致越界访问只有一个线程不能。
在您的特定情况下,如果每个线程由于使用不同的 ID 而写入非重叠内存,则在访问数组时不可能出现竞争条件。但是,在分配 ID时可能存在竞争条件,导致两个线程接收相同的 ID ...因此您需要使用锁或其他方式来保证不会发生这种情况。
您需要注意的主要事情是如何或何时分配 2D 数组。如果所有分配都发生在工作线程开始访问数组之前,并且每个工作线程在线程的生命周期内仅读取和写入主数组的“行”之一,并且它是唯一的线程访问该行,那么访问或更新数组中的条目应该不会有任何线程问题。
如果只有一个线程正在写入一行,但多个线程可能正在从同一行读取,那么您可能需要制定一些同步计划,否则您的读者可能偶尔会看到由于并发写入者的部分写入而导致的不一致/不连贯的数据.
如果每个工作线程都硬绑定到主数组中的单个“行”,那么工作线程本身也可以分配和重新分配每行所需的内存,包括更新主数组中的插槽以指向由线程(重新)分配的行数据。主数组中的指针槽不应该有争用,因为只有这个工作线程对该槽感兴趣。确保在任何工作线程开始之前分配主数组。对于这种情况,还要确保您的 C RTL malloc 实现是线程安全的。(您可能必须在构建选项中选择线程安全的 RTL)