Home > Software engineering >  What am I getting wrong in this Busy Waiting solution using Strict Alteration with C and Posix threa
What am I getting wrong in this Busy Waiting solution using Strict Alteration with C and Posix threa

Time:10-20

I am supposed to reproduce the Strict Alternation algorithm using C and Posix Threads.

I coded the below solution but the printfs aren't being outputed at all. Sometimes just the my_id is outputed but that's all. What am I doing or understanding wrong?

For example, this was the output of one of the times I ran this code: enter image description here

Oher output: enter image description here

Here is the code I did:

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

int count = 0;
int turn = 1;

struct arg_struct {
    int my_id;
    int other;
};

void *runner(void *param) {
    struct arg_struct *args = (struct arg_struct *)param;
    int my_id = args -> my_id;
    int other = args -> other;
    printf("my_id %d\n", my_id);
    printf("other %d\n", other);
    printf("Running p_thread %d\n", my_id);

    while(1) {
        while (turn != my_id) { }

        // critical section
        count = count   my_id;
        printf("Critical section of p_thread %d, count was incremented by %d and is now %d\n", my_id, my_id, count);

        turn = other;

        // not critical section
        printf("Not critical section of p_thread %d\n", my_id);
    }

    pthread_exit(NULL);
}

int main(int argc, char *argv[]) {
    int thr_id1, thr_id2;
    pthread_t p_thread1;
    pthread_t p_thread2;

    struct arg_struct args_p_thread1;
    args_p_thread1.my_id = 1;
    args_p_thread1.other = 2;

    struct arg_struct args_p_thread2;
    args_p_thread2.my_id = 2;
    args_p_thread2.other = 1;

    thr_id1 = pthread_create(&p_thread1, NULL, runner, (void*)&args_p_thread1);
    thr_id2 = pthread_create(&p_thread2, NULL, runner, (void*)&args_p_thread2);

    return 0;
}

CodePudding user response:

The variable you use for your parameters is reused between the threads.

Your global variables are not immediately suitable for sharing between threads, so it’s possible they do not see a new value of turn and get stuck in your inner while loop.

Your main loop exits without waiting for the threads, so they may not get a chance to do much. Your program will exit at the end of the main thread, it will not automatically wait for your other threads.

CodePudding user response:

This code works for me on Repl.it.

I added volatile and pthread_join

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

int count = 0;
volatile int turn = 1;

struct arg_struct {
    int my_id;
    int other;
};

void *runner(void *param) {
    struct arg_struct *args = (struct arg_struct *)param;
    int my_id = args -> my_id;
    int other = args -> other;
    printf("my_id %d\n", my_id);
    printf("other %d\n", other);
    printf("Running p_thread %d\n", my_id);

    while(1) {
        while (turn != my_id) { }

        // critical section
        count = count   my_id;
        printf("Critical section of p_thread %d, count was incremented by %d and is now %d\n", my_id, my_id, count);

        turn = other;

        // not critical section
        printf("Not critical section of p_thread %d\n", my_id);
    }

    pthread_exit(NULL);
}

int main(int argc, char *argv[]) {
    int thr_id1, thr_id2;
    pthread_t p_thread1;
    pthread_t p_thread2;

    struct arg_struct args_p_thread1;
    args_p_thread1.my_id = 1;
    args_p_thread1.other = 2;

    struct arg_struct args_p_thread2;
    args_p_thread2.my_id = 2;
    args_p_thread2.other = 1;

    thr_id1 = pthread_create(&p_thread1, NULL, runner, (void*)&args_p_thread1);
    thr_id2 = pthread_create(&p_thread2, NULL, runner, (void*)&args_p_thread2);

  int join = 0;
    pthread_join(&p_thread1, &join);
  
  pthread_join(&p_thread2, &join);
  
    return 0;
}
  • Related