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

时间:2019-06-19 20:49:46

标签: c concurrency parallel-processing pthreads posix

为了更快地计算,请尝试使我的方法由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的。

谢谢

1 个答案:

答案 0 :(得分:0)

如果您使用的是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