我在从多个线程访问数组时遇到问题。我写了一个 struct
,它收集了我想做的工作所需的所有信息。
结构定义如下:
struct thread_blk
{
size_t th_blk_count;
size_t th_blk_size;
size_t th_blk_current;
size_t* th_blk_i_start;
void* data;
pthread_t* th_id;
ThreadBlockAdaptive th_blk_adapt;
};
想法是从多个线程填充一个数组,每个线程都在数组的一个分隔内存字段上工作。
th_blk_count
字段表示必须 接受治疗,th_blk_size
字段表示一个 block 的大小,th_blk_current
字段表示处理的 block (它们是 从0
到n
列出),th_blk_i_start
是一个包含数组索引的数组 必须填写。
仅应用于 thread_blk
struct
的单个函数无法正常工作:
int startAllThreadBlock(struct thread_blk* th_blk, worker_func f)
{
int res = 0;
for(size_t i = 0; i < th_blk->th_blk_count; ++i)
{
res |= pthread_create(th_blk->th_id + i, NULL, f, th_blk);
th_blk->th_blk_current++;
}
return res;
}
事实上,th_blk_current
字段没有正确递增。我用它来检索用作间隔的 th_blk_i_start
索引。结果,我的工作人员(如下所示)正在处理 double
数组的相同索引。
这是我在 startAllThreadBlock
函数中使用的函数:
void* parallel_for(void* th_blk_void)
{
ThreadBlock th_blk = (ThreadBlock)th_blk_void;
size_t i = getThreadBlockStartIndex(th_blk, getThreadBlockCurrentIndex(th_blk));
printf(
"Running thread %p\n"
" -Start index %zu\n\n",
pthread_self(),
i
);
if(getThreadBlockCurrentIndex(th_blk) == (getThreadBlockCount(th_blk) - 1))
{
for(; i < MAX; ++i)
{
result[i] = tan(atan((double)i));
}
}
else
{
size_t threshold = getThreadBlockStartIndex(th_blk, getThreadBlockCurrentIndex(th_blk) + 1);
for(; i < threshold; ++i)
{
result[i] = tan(atan((double)i));
}
}
return NULL;
}
ThreadBlock 只是 thread_blk*
的类型定义; result
是double
的数组。
我很确定问题出在 startAllThreadBlock
周围(如果我使用 1 秒 sleep
一切都按预期运行)。但我不知道如何修复它。
有人有想法吗?
感谢您的回答。
更新
在 worker 中放置增量解决了这个问题。但我认为这并不安全,原因是一些程序员提到的。
void* parallel_for(void* th_blk_void)
{
ThreadBlock th_blk = (ThreadBlock)th_blk_void;
size_t i = getThreadBlockStartIndex(th_blk, getThreadBlockCurrentIndex(th_blk));
size_t n;
if(getThreadBlockCurrentIndex(th_blk) == (getThreadBlockCount(th_blk) - 1))
{
n = MAX;
}
else
{
n = getThreadBlockStartIndex(th_blk, getThreadBlockCurrentIndex(th_blk) + 1);
}
incThreadBlockCurrent(th_blk);
printf(
"Running thread %p\n"
" -Start index %zu\n\n",
pthread_self(),
i
);
for(; i < n; ++i)
{
result[i] = tan(atan((double)i));
}
return NULL;
}
它会在 th_blk_current
上使用互斥锁来完成吗?
最佳答案
我认为这里的问题是您认为线程获得了结构的副本。它没有,它得到一个指针。所有线程都获得指向相同 结构的指针。因此对结构的任何更改都会影响所有线程。
您需要想出一种方法将单独的数据传递给单独的线程。例如,一个仅包含线程特定数据的线程特定结构,您动态分配该结构的一个实例以传递给线程。
关于C pthread 从多个线程访问数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41084092/