首页 > 解决方案 > 使用 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;
    
}

标签: cpthreadsmutex

解决方案


互斥锁不会强制 D 和 B 或 C 之间的任何排序。

要进行这样的排序,您需要稍后运行 D(在 B 和 C 加入之后),或者在 B 和 C 完成时让 D 等待设置的条件。

mutex1如果您实施适当的等待,mutex2实际上不需要。如果稍后启动 D,则不需要互斥锁,或者如果您将在条件变量上使用等待,则只需要一个互斥锁

此外,还不清楚为什么您需要在 D 中使用循环。您只有两个变量的总和。


对于实际应用,并行数组处理通常通过按范围划分数组来完成,而不是按模数。对于像 20 这样的小尺寸,这根本没有意义。您更喜欢线程池线程以避免线程启动开销和控制线程数。当然,evenSum+oddSum你不需要线程。


推荐阅读