【问题标题】:How to get one correct value from a function which is parallelized by multi-threads如何从多线程并行化的函数中获取一个正确的值
【发布时间】:2019-11-02 15:56:07
【问题描述】:

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

谢谢

【问题讨论】:

    标签: c concurrency parallel-processing pthreads posix


    【解决方案1】:

    如果你在 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
    

    【讨论】:

    • 非常感谢@Keine_Lust!现在该值是静态的。但我的预期结果不匹配。我需要并发,处理相同的值而不是按线程数克隆。
    • 我知道我也应该分工!非常感谢@Keine_Lust!如同一位老板! :D
    猜你喜欢
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多