Multithreaded (C) program threads not terminating

Viewed 2198

I am trying to finish up a program that uses multiple threads (3) to distribute a hypothetical scholarship of $4000. Each time a thread processes, it "locks" the "critical section" and blocks the other threads from taking out their chunk from the sum. With each access, the thread is meant to take 25% of the remaining sum of "scholarship" money. The output is the amount that each thread takes as it gains access to the scholarship.

My program seems to be processing proper output so far, but when it gets to the end there seems to be a catch. Each process/thread gets to a point where it doesn't terminate or exit and the program just becomes stagnant and doesn't complete. I feel like the threads are processing but not meeting a terminating condition (scholarship is all gone). The last function totalCalc() is never reached. Does anyone see anything that I don't, which could help alleviate this problem or push the program to completion?

#include <stdio.h>
#include <pthread.h>
#include <math.h>

#define PERCENTAGE 0.25

pthread_mutex_t mutex; // protecting critical section
int scholarship = 4000,
                  total = 0;
void *A();
void *B();
void *C();
void *totalCalc();

int main(){ 

    pthread_t tid1,
              tid2,
              tid3;

    //pthread_setconcurrency(3); 

    pthread_create(&tid1, NULL, (void *(*)(void *))A, NULL );
    pthread_create(&tid2, NULL, (void *(*)(void *))B, NULL );
    pthread_create(&tid3, NULL, (void *(*)(void *))C, NULL );
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    pthread_join(tid3,NULL);

    totalCalc();


    return 0;

}

void *A(){
    float result;
    while(scholarship > 0){
        sleep(2);
        pthread_mutex_lock(&mutex);
        result = scholarship * PERCENTAGE;
        result = ceil(result);
        total = total + result;
        scholarship = scholarship - result;
        if( result >= 1){
            printf("A = ");
            printf("%.2f",result);
            printf("\n");
        }
        if( scholarship < 1){
            pthread_exit(0);
            printf("Thread A exited\n");
            return;
        }
        pthread_mutex_unlock(&mutex);
    }

    pthread_exit(0);

}

void *B(){
    float result;
    while(scholarship > 0){
        sleep(1);
        pthread_mutex_lock(&mutex);
        result = scholarship * PERCENTAGE;
        result = ceil(result);
        total = total + result;
        scholarship = scholarship - result;
        if( result >= 1){
            printf("B = ");
            printf("%.2f",result);
            printf("\n");
        }
        if( scholarship < 1){
            pthread_exit(0);
            printf("Thread B exited\n");
            return;
        }           
        pthread_mutex_unlock(&mutex);
    }

    pthread_exit(0);
}

void *C(){
    float result;
    while(scholarship > 0){
        sleep(1);
        pthread_mutex_lock(&mutex);
        result = scholarship * PERCENTAGE;
        result = ceil(result);
        total = total + result;
        scholarship = scholarship - result;
        if( result >= 1){
            printf("C = ");
            printf("%.2f",result);
            printf("\n");
        }
        if( scholarship < 1){
            pthread_exit(0);
            printf("Thread C exited\n");
            return;
        }           
        pthread_mutex_unlock(&mutex);       
    }

    pthread_exit(0);
}

void *totalCalc(){
    printf("Total given out: ");
    printf("%d", total);
    printf("\n");
}

Output:

B = 1000.00
C = 750.00
A = 563.00
B = 422.00
C = 317.00
B = 237.00
C = 178.00
A = 134.00
B = 100.00
C = 75.00
B = 56.00
C = 42.00
A = 32.00
B = 24.00
C = 18.00
B = 13.00
C = 10.00
A = 8.00
B = 6.00
C = 4.00
B = 3.00
C = 2.00
A = 2.00
B = 1.00
C = 1.00
B = 1.00
C = 1.00
^C
3 Answers
Related