我遇到从多个线程访问数组的问题。我写了一个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
字段表示块的大小th_blk_current
字段代表已处理的块(它们是
从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*
上的一个typedef; result
是double
的数组。
我非常确定问题出在startAllThreadBlock
附近(如果我使用1秒sleep
一切按预期运行)。但我不知道如何解决它。
有人有想法吗?
感谢您的回答。
在工作人员中放置增量解决了问题。但我认为这不安全,因为一些程序员老兄提到了。
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
no?
答案 0 :(得分:1)
我认为这里的问题是你认为线程传递了结构的副本。它没有,它得到一个指针。所有线程都获得指向相同结构的指针。因此,对结构的任何更改都将影响所有线程。
您需要想出一种将单个数据传递到各个线程的方法。例如,一个特定于线程的结构,只包含特定于线程的数据,并动态分配该结构的一个实例以传递给该线程。