C pthread 从多个线程访问数组

标签 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字段表示一个 block 的大小,
  • th_blk_current 字段表示处理的 block (它们是 从 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* 的类型定义; resultdouble 的数组。

我很确定问题出在 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/

相关文章:

c - 段错误(核心已转储)

php - 软呢帽 PHP "failed to open stream: Permission denied"

linux - 如何区分 2 个目录中的所有文件并将其重定向到其他文件

c - 读写并发

c - 从 main 调用 pthread_exit 可以吗?

c++ - 锁定和操作需要很长时间

c - 当字符串为数字时C语言

c - 当指针指向一个新字符串时,分配给该指针寻址的字符串的内存会发生什么?

linux - 将用户值传递给 AWK 中的变量。我错过了什么?

c++ - pthread_create 中错误 4 的段错误