线程返回值与预期输出

时间:2016-10-11 03:21:44

标签: c multithreading pthreads

我正在开发一个项目,它需要与下面的程序有些类似的功能,所以我试图创建一个更简单的程序来调试我的大型程序。我正在创建的线程返回的值与它们的预期输出不一致,但它们的返回值不是随机的。看起来线程似乎从其他线程返回值,或者它们返回的变量(“tmp”)正在更新。

预期的输出应该是......

0 1

1 2

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

struct Numbers {
    int x;
    int y;
};

void *go(void* param)
{
    struct Numbers* nums = (struct Numbers*) param;
    int sum = nums -> x + nums -> y;

    return (void*) sum;
}

int main()
{
    int result[2][2];
    int tmp;

    pthread_t thread[2][2];

    int i, j;
    for(i=0;i<2;i++)
    {
        for(j=0;j<2;j++)
        {
            struct Numbers nums;
            nums.x = i;
            nums.y = j;

            pthread_create(&thread[i][j], NULL, go, &nums);
        }
    }

    for(i=0;i<2;i++)
    {
        for(j=0;j<2;j++)
        {
            pthread_join(thread[i][j], (void*) &tmp);
            result[i][j] = tmp;
        }
    }

    for(i=0;i<2;i++)
    {
        for(j=0;j<2;j++)
        {
            printf("%d\t", result[i][j]);
        }
        printf("\n");
    }

    return 0;
}

1 个答案:

答案 0 :(得分:2)

您传递的变量的地址可能在线程开始执行后不存在,或者至少会被多个线程看到,或者是一个数据争用,因为一个线程在其他人读取它时写入它。

一般的解决方案是动态分配线程的参数和结果,让调用者和线程以这种方式进行通信。

示例:

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

struct threadargs {
    int x;
    int y;
};

struct threadresults {
    int sum;
    int product;
};

void* threadfunc(void* args_void) {
    // Get thread args in usable type.
    struct threadargs* args = args_void;
    struct threadresults* results = NULL;

    //Compute.
    int sum = args->x + args->y;
    int product = args->x * args->y;

    // Return the result.    
    results = malloc(sizeof(*results));
    results->sum = sum;
    results->product = product;

    free(args);
    return results;
}

int main()
{
    pthread_t thread[2][2];
    struct threadresults* results[2][2] = {0};

    int i, j;
    for (i = 0;i < 2; ++i) {
        for (j = 0; j < 2; ++j) {
            struct threadargs* args = malloc(sizeof(*args));
            args->x = i;
            args->y = j;

            pthread_create(&thread[i][j], NULL, threadfunc, args);
        }
    }

    for (i = 0; i < 2; i++) {
        for (j = 0; j < 2; j++) {
            void* result;
            pthread_join(thread[i][j], &result);
            results[i][j] = result;
        }
    }

    for (i = 0; i < 2; i++) {
        for (j = 0; j < 2; j++) {
            printf("sum: %d\tproduct: %d\n",
                   results[i][j]->sum, results[i][j]->product);
        }
    }

    for (i = 0; i < 2; i++) {
        for (j = 0; j < 2; j++) {
            free(results[i][j]);
        }
    }

    return 0;
}