如何从一个由多线程并行化的函数中获取一个正确的值

How to get one correct value from a function which is parallelized by multi-threads

为了加快计算速度,尝试使我的方法由 4 个线程并行化。线程在哪里进行 4 个单独的计算,无论我是否期望并发操作和单个变量。

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

static int x, j=5;

void *print_count (void *dummy)
{
  for(int i=0;i<1000;i++){
  x+=j;
  }
}

int main ()
{
pthread_t p1, p2, p3, p4;

pthread_create (&p1, NULL, print_count, NULL);
pthread_create (&p2, NULL, print_count, NULL);
pthread_create (&p3, NULL, print_count, NULL);
pthread_create (&p4, NULL, print_count, NULL);

pthread_join (p1, NULL);
pthread_join (p2, NULL);
pthread_join (p3, NULL);
pthread_join (p4, NULL);

printf("Actual output: %d \nExpected output: 5000\n", x);

return 0;

}

我希望输出 5000,因为增量为 5 并循环 1000 次。 但实际输出首先不是静态的,它总是在变化,它接近 5000 的 4 倍,因为线程正在单独计算 print_count。

谢谢

如果您使用的是 C11,则可以使用 _Atomic

当然每个线程都需要在一定范围内工作(不是完整的集合),传递一个struct:

#include <stdio.h>
#include <stdatomic.h>
#include <pthread.h>

_Atomic int x;
static int j = 5;

struct range {
    int from, to;
};

void *print_count(void *data)
{
    struct range *range = data;

    for (int i = range->from; i < range->to; i++) {
        x += j;
    }
    return NULL;
}

int main(void)
{
    pthread_t p1, p2, p3, p4;
    struct range ranges[] = {
        {0, 250},
        {250, 500},
        {500, 750},
        {750, 1000}
    };

    pthread_create(&p1, NULL, print_count, &ranges[0]);
    pthread_create(&p2, NULL, print_count, &ranges[1]);
    pthread_create(&p3, NULL, print_count, &ranges[2]);
    pthread_create(&p4, NULL, print_count, &ranges[3]);

    pthread_join(p1, NULL);
    pthread_join(p2, NULL);
    pthread_join(p3, NULL);
    pthread_join(p4, NULL);

    printf("Actual output: %d \nExpected output: 5000\n", x);
    return 0;
}

或复合文字:

pthread_create(&p1, NULL, print_count, (int []){  0,  250});
pthread_create(&p2, NULL, print_count, (int []){250,  500});
pthread_create(&p3, NULL, print_count, (int []){500,  750});
pthread_create(&p4, NULL, print_count, (int []){750, 1000});

...

void *print_count(void *data)
{
    int *range = data;

    for (int i = range[0]; i < range[1]; i++) {
        x += j;
    }
    return NULL;
}

为了分任务

输出:

Actual output: 5000 
Expected output: 5000