Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 线程返回值与预期输出不一致_C_Multithreading_Pthreads - Fatal编程技术网

C 线程返回值与预期输出不一致

C 线程返回值与预期输出不一致,c,multithreading,pthreads,C,Multithreading,Pthreads,我正在从事一个项目,该项目需要与下面的程序类似的功能,因此我尝试创建一个更简单的程序来调试我的大型程序。我正在创建的线程返回的值与其预期输出不一致,但它们的返回值不是随机的。似乎线程正在从其他线程返回值,或者它们返回的变量(“tmp”)正在更新 预期输出应为 01 1 2 #包括 #包括 结构数{ int x; int-y; }; void*go(void*param) { 结构编号*nums=(结构编号*)参数; int sum=nums->x+nums->y; 返回(无效*)金额; } in

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

预期输出应为

01

1 2

#包括
#包括
结构数{
int x;
int-y;
};
void*go(void*param)
{
结构编号*nums=(结构编号*)参数;
int sum=nums->x+nums->y;
返回(无效*)金额;
}
int main()
{
int结果[2][2];
int tmp;
pthread_t thread[2][2];
int i,j;

对于(i=0;i您正在传递一个变量的地址,该变量在线程开始执行时可能不存在,或者至少会被多个线程看到,或者是一个线程写入而其他线程读取时的数据竞争

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

例如:

#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;
}
#包括
#包括
#包括
结构线程参数{
int x;
int-y;
};
结构线程结果{
整数和;
int产品;
};
void*threadfunc(void*args\u void){
//获取可用类型的线程参数。
struct threadargs*args=args\u void;
struct threadresults*results=NULL;
//计算。
int sum=args->x+args->y;
int product=args->x*args->y;
//返回结果。
结果=malloc(sizeof(*结果));
结果->总和=总和;
结果->产品=产品;
免费(args);
返回结果;
}
int main()
{
pthread_t thread[2][2];
struct threadresults*results[2][2]={0};
int i,j;
对于(i=0;i<2;++i){
对于(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);
}
}
对于(i=0;i<2;i++){
对于(j=0;j<2;j++){
无效*结果;
pthread_join(线程[i][j],&result);
结果[i][j]=结果;
}
}
对于(i=0;i<2;i++){
对于(j=0;j<2;j++){
printf(“总和:%d\t产品:%d\n”,
结果[i][j]->和,结果[i][j]->积);
}
}
对于(i=0;i<2;i++){
对于(j=0;j<2;j++){
免费(结果[i][j]);
}
}
返回0;
}

考虑
nums
的生存期与线程可能尝试访问它的时间相比。您是否保证
nums
不会为所有线程调用重写?@GManNickG我有一个完美的“ohhhh”时刻。因此,在创建线程之前准备所有数据是我唯一的选择(嵌套for循环之外)或者有更好的选择吗?您只需要在嵌套循环之外保留空间:
struct Numbers nums[2][2];
您可以在循环内部填充数据。另一种选择是使用动态内存分配,即
malloc
。此外,
(void*)&tmp
是非常错误的;您确实需要
void**
(即指向类型为
void*
)的变量的指针,
pthread\u join
将其视为
void**
,并尝试在那里写入
void*
,有时
void*
大于
int
,因此溢出
tmp
。(例如,Windows是这些平台之一,但是您可能没有在Windows上使用pthreads)
#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;
}