c - 使用 pthread_mutex_t 的线程之间的同步问题
问题描述
基本上我需要让三个线程 B、C、D 同时工作。线程 B 对全局数组 X 中的偶数索引求和,C 对 X 中的奇数索引求和,D 对两个结果求和,而 B 和 C 仍在求和。我使用了两个互斥锁来这样做,但它不能正常工作。在下面代码中给出的数组 X 中,结果应该是:evenSum = 47,oddSum = 127,bothSum = 174。非常感谢任何帮助!谢谢!!
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#define SIZE 20
int X[SIZE] = {5,4,5,3,7,9,3,3,1,2,9,0,3,43,3,56,7,3,4,4};
int evenSum = 0;
int oddSum = 0;
int bothSum = 0;
//Initialize two mutex semaphores
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
void* sum_even_indexes(void* args){
int i;
for(i=0 ; i<20 ; i+=2){
pthread_mutex_lock(&mutex1);
evenSum+=X[i];
pthread_mutex_unlock(&mutex1);
}
pthread_exit(NULL);
}
void* sum_odd_indexes(void* args){
int i;
for(i=1 ; i<20 ; i+=2){
pthread_mutex_lock(&mutex2);
oddSum+=X[i];
pthread_mutex_unlock(&mutex2);
}
pthread_exit(NULL);
}
void* sum_of_both(void* args){
int i;
for(i=0 ; i<SIZE ; i++){
pthread_mutex_lock(&mutex1);
pthread_mutex_lock(&mutex2);
bothSum += (evenSum+oddSum);
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
}
pthread_exit(NULL);
}
int main(int argc, char const *argv[]){
pthread_t B,C,D;
/***
* Create three threads:
* thread B : Sums up the even indexes in the array X
* thread C : Sums up the odd indexes in the array X
* thread D : Sums up both B and C results
*
* Note:
* All threads must work simultaneously
*/
pthread_create(&B,NULL,sum_even_indexes,NULL);
pthread_create(&C,NULL,sum_odd_indexes,NULL);
pthread_create(&D,NULL,sum_of_both,NULL);
//Wait for all threads to finish
pthread_join(B,NULL);
pthread_join(C,NULL);
pthread_join(D,NULL);
pthread_mutex_destroy(&mutex1);
pthread_mutex_destroy(&mutex2);
//Testing Print
printf("Odds Sum = %d\n",oddSum);
printf("Evens Sum = %d\n",evenSum);
printf("Both Sum = %d\n",bothSum);
return 0;
}
解决方案
互斥锁不会强制 D 和 B 或 C 之间的任何排序。
要进行这样的排序,您需要稍后运行 D(在 B 和 C 加入之后),或者在 B 和 C 完成时让 D 等待设置的条件。
mutex1
如果您实施适当的等待,mutex2
实际上不需要。如果稍后启动 D,则不需要互斥锁,或者如果您将在条件变量上使用等待,则只需要一个互斥锁
此外,还不清楚为什么您需要在 D 中使用循环。您只有两个变量的总和。
对于实际应用,并行数组处理通常通过按范围划分数组来完成,而不是按模数。对于像 20 这样的小尺寸,这根本没有意义。您更喜欢线程池线程以避免线程启动开销和控制线程数。当然,evenSum+oddSum
你不需要线程。
推荐阅读
- python - Python将csv文件转换为Json问题
- node.js - Mongoose:如何使用聚合和展平子文档来列出
- android - 如何从 Firebase 数据库制作 .txt 文件?
- angular - Angular ng build 与 ng 服务性能
- batch-file - 默认选择(批量)在超时后不起作用
- android - 有没有办法在 for 循环中加载多个 URL
- c# - Unity:通过 TMP_DefaultControls 从脚本创建的 InputField 没有克拉
- azure - 如何将 > 8K 的敏感二进制信息传输到 Azure IoT 设备
- strapi - Strapi:“created_by”、“updated_by”字段来跟踪内容的变化
- flutter - 我们可以下载视频并使用颤振播放而不将其添加到资产中吗?