C pthread从多个线程访问数组

时间:2016-12-11 07:55:41

标签: c linux pthreads

我遇到从多个线程访问数组的问题。我写了一个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字段代表已处理的块(它们是 从0n列出,
  • 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; resultdouble的数组。

我非常确定问题出在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?

上的互斥锁来实现

1 个答案:

答案 0 :(得分:1)

我认为这里的问题是你认为线程传递了结构的副本。它没有,它得到一个指针。所有线程都获得指向相同结构的指针。因此,对结构的任何更改都将影响所有线程。

您需要想出一种将单个数据传递到各个线程的方法。例如,一个特定于线程的结构,只包含特定于线程的数据,并动态分配该结构的一个实例以传递给该线程。