如何正确通过结构体将数组传递给线程函数并实现分段求和汇总
我太懂这种卡好几天找不到突破口的感觉了!刚好之前做过多线程分块求和的实现,给你整理了一套完整的解决方案,直接就能用:
完整实现代码
#include <pthread.h> #include <stdlib.h> #include <stdio.h> #define NUMBER_OF_THREADS 2 // 定义传递给线程的结构体:打包所有需要的参数 typedef struct { int* input_array; // 待求和的原始数组 int start_idx; // 当前线程负责计算的起始索引 int end_idx; // 当前线程负责计算的结束索引(左闭右开) int* result_array; // 存储各线程求和结果的数组 int result_idx; // 当前线程结果在result_array中的位置 } ThreadData; // 线程执行函数:计算指定区间的数组和 void* sum_part(void* arg) { // 将void*参数转换为我们定义的结构体指针 ThreadData* data = (ThreadData*)arg; int sum = 0; // 遍历负责的区间求和 for (int i = data->start_idx; i < data->end_idx; i++) { sum += data->input_array[i]; } // 将结果存入指定位置 data->result_array[data->result_idx] = sum; // 线程退出 pthread_exit(NULL); } int main() { // 示例待求和数组(你可以替换成自己的数组) int input[] = {1, 2, 3, 4, 5, 6, 7, 8}; int input_size = sizeof(input) / sizeof(input[0]); // 存储每个线程的求和结果,长度和线程数一致 int results[NUMBER_OF_THREADS] = {0}; // 线程ID数组,用于管理创建的线程 pthread_t threads[NUMBER_OF_THREADS]; // 每个线程对应一个ThreadData结构体,打包参数 ThreadData thread_data[NUMBER_OF_THREADS]; // 给每个线程分配计算区间 int elements_per_thread = input_size / NUMBER_OF_THREADS; for (int i = 0; i < NUMBER_OF_THREADS; i++) { thread_data[i].input_array = input; thread_data[i].start_idx = i * elements_per_thread; // 处理边界:最后一个线程负责剩下的所有元素(避免数组长度不能被线程数整除) if (i == NUMBER_OF_THREADS - 1) { thread_data[i].end_idx = input_size; } else { thread_data[i].end_idx = (i + 1) * elements_per_thread; } thread_data[i].result_array = results; thread_data[i].result_idx = i; // 创建线程,传递结构体指针作为参数 int rc = pthread_create(&threads[i], NULL, sum_part, (void*)&thread_data[i]); if (rc != 0) { printf("创建线程%d失败,错误码:%d\n", i, rc); exit(EXIT_FAILURE); } } // 必须等待所有线程执行完毕,否则主程序可能提前退出导致结果错误 for (int i = 0; i < NUMBER_OF_THREADS; i++) { pthread_join(threads[i], NULL); } // 汇总所有线程的结果得到总值 int total_sum = 0; for (int i = 0; i < NUMBER_OF_THREADS; i++) { total_sum += results[i]; } printf("数组总和为:%d\n", total_sum); return EXIT_SUCCESS; }
关键细节说明
- 结构体设计:我特意加了
start_idx和end_idx,这是多线程求和的核心——让每个线程负责数组的一个子区间,避免重复计算。如果直接让所有线程处理整个数组,结果会重复累加,完全达不到并行计算的目的。 - 参数类型转换:pthread的线程函数要求参数必须是
void*类型,所以我们把结构体指针强制转换后传递,在线程函数里再转回来使用,这是多线程编程里的常规操作。 - 线程等待:
pthread_join一定要调用!如果主程序不等线程跑完就直接结束,线程可能还没完成计算就被终止,结果数组里的数据会是错误的。 - 边界处理:最后一个线程负责处理剩下的所有元素,这样即使数组长度不能被线程数整除,也不会遗漏任何元素。
编译的时候记得链接pthread库,比如用gcc的话:gcc your_file.c -o sum_threads -lpthread
内容的提问来源于stack exchange,提问作者alm2022
相关产品推荐
相关产品推荐

