C 线程返回值与预期输出不一致
我正在从事一个项目,该项目需要与下面的程序类似的功能,因此我尝试创建一个更简单的程序来调试我的大型程序。我正在创建的线程返回的值与其预期输出不一致,但它们的返回值不是随机的。似乎线程正在从其他线程返回值,或者它们返回的变量(“tmp”)正在更新 预期输出应为 01 1 2C 线程返回值与预期输出不一致,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
#包括
#包括
结构数{
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;
}