0

Trying to implement the critical section of this program to actually swap between both threads correctly as stated later in the description.

I am trying to do a problem for my Operating Systems course. The problem is that I need to input two files, one of each are put into their separate threads, they will read through the file till they hit a line with the number "0". Then the other thread is supposed to run by the same rules.

This program is supposed to take two file input and figure out the message by concatenating both of the inputs from the files in a specific order and then printing out the output after it has deciphered it.

The inputs of these two files as shown below

Person1         Person2          
---------       ---------- 
t                  0
0                  h
i                  0
s                  0
0                  i
0                  s
0                  a
t                  0
e                  0
0                  s
t                  0

the above inputs should result in a string with this output

Example: “thisisatest”

Currently what is going wrong with the assignment is that it is not swapping correctly between the two threads and sitting in infinite loops.

Like I said above I am trying to solve this assignment by use of Mutexes and Pthreads

Below is the current implementation of my code

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



static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static char *charArray[1000];

void *threadPerson1(void *value){

    FILE *fPTR;
    char buffer[2];

    char *fileName = "Person1.txt";

    fPTR = fopen(fileName, "r");

    if (fPTR == NULL){

        printf("was unable to open: %s\n", fileName);
        return NULL;
    }

    while(1){

        //Entering the critical section
        pthread_mutex_lock(&mutex);

        fscanf(fPTR, "%s", buffer);
        printf("This is Person1: %s\n", buffer);



        if(buffer != "0"){

            charArray[count] = buffer;
            count++;
        }
        if(buffer == "0"){

            pthread_mutex_unlock(&mutex);
        }
        //exiting the critical section
    }


}

void *threadPerson2(void *value){

    FILE *fPTR;
    char buffer[2];

    char *fileName = "Person2.txt";

    fPTR = fopen(fileName, "r");    

    if (fPTR == NULL){

        printf("was unable to open: %s\n", fileName);
        return NULL;
    }

    while(1){

        //entering the critical section
        pthread_mutex_lock(&mutex);

        fscanf(fPTR, "%s", buffer);
        printf("This is Person2: %s\n", buffer);



        if(buffer != "0"){

            charArray[count] = buffer;
            count++;
        }
        if(feof(fPTR)){

            printf("read end of file of: Person2\n");
            fclose(fPTR);
            return NULL;
        }
        if(buffer == "0"){

            pthread_mutex_unlock(&mutex);
        }
        //exiting the critical section


    }


}


int main(int argc, char **argv){


    pthread_t thread1;
    pthread_t thread2;

    pthread_create(&thread1, NULL, threadPerson1, NULL);
    pthread_create(&thread2, NULL, threadPerson2, NULL);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);


    for(int x = 0; x < 1000; x++){

        if(charArray[x] == NULL){

            printf("\n");
            break;
        }else{

            printf("%s", charArray[x]);
        }
    }

    return 0;
}
Jeffrey Hennen
  • 63
  • 1
  • 1
  • 8
  • And the question is? – Marco Bonelli Sep 30 '19 at 06:32
  • Sorry, did I not mention it? How would I end up changing the critical section part to make it function as I need it to? – Jeffrey Hennen Sep 30 '19 at 06:33
  • 1
    Please read [ask]. Edit the question to include what you want the code to do and what it does instead. – klutt Sep 30 '19 at 06:49
  • more info, please. 1st thread reads until finds 0, then hit 2nd thread and waits. 2nd thread reads until finds 0 and... what? Also, what would happen if there is no '0' in the file? Do both treads read same file or not? If there are two files what would happen if there is no '0' in 2nd file? Please, draw diagram, if possible. At first sight, use barrier. – Ivan Ivanov Sep 30 '19 at 07:25
  • Threads go back and forth and then if there are no 0s it would just read till end of file and then continue on with other thread and finish – Jeffrey Hennen Sep 30 '19 at 07:38
  • Threads read their own file corresponding to the specific person as in the code. – Jeffrey Hennen Sep 30 '19 at 07:39
  • When one hits a 0 it just sends to other thread and then gets the new line on the other file – Jeffrey Hennen Sep 30 '19 at 07:39
  • 2
    You seem to compare pointers not strings themselves so `buffer != "0"` condition is always `true`. You either need to use string comparison functions like `strcmp` or read a single char to compare against a char constant. – Dmytro Mukalov Sep 30 '19 at 08:54
  • Do you *have* to use threads for this? Do they *have* to synchronize? I don't see why the task presented requires that. As the example input is presented, all you need to do is read each file and copy out the non-zero bytes to corresponding positions in the array. There is no inherent sensitivity to the order in which positions in the array are filled. – John Bollinger Oct 01 '19 at 12:20
  • Yes john, you can easily do this problem without using threads and synchronization. the point is to use threads and synchronize them. – Jeffrey Hennen Oct 02 '19 at 02:27
  • @JeffreyHennen: Did you add condition variables signalling like I suggested in my answer? – Erik Alapää Oct 04 '19 at 12:49
  • The way i was able to solve the problem was creating two mutexs and then use one mutex on the open and another mutex for the close, so it is opening and closing the other's mutex and thus alternating – Jeffrey Hennen Oct 05 '19 at 03:49
  • @JeffreyHennen from https://linux.die.net/man/3/pthread_mutex_unlock, if you unlock a mutex another thread has locked, that is UB, Undefined Behaviour, a critical violation of the API. See also https://stackoverflow.com/questions/5454746/pthread-mutex-lock-unlock-by-different-threads – Erik Alapää Oct 06 '19 at 08:35

1 Answers1

1

At least two things are incorrect in your program. First of all, if one thread releases the mutex, you are not guaranteed that the scheduler will allow the other thread will run, the releasing thread may very well go on and reacquire the mutex right away. Use a condition variable, read its manpages. Also, here are some examples, in particular 4-8: Multithreaded programming guide

Two, when you reach end of file, you need to release the mutex to clean up. Easiest way to do it is what we call RAII in C++, i.e. use a resource handle that releases the mutex when the handle object goes out of scope. You can do similar things in C e.g. by registering a cleanup function, or a 'goto' to end of function with cleanup code called from there.

Erik Alapää
  • 2,585
  • 1
  • 14
  • 25