0

I am trying read and write from a shared file between processes. The file has 6 lines that are meant to be read and then a new line should be inserted by one process. To be more precise i want my reading process to be done simultaneously but the writing process to be one by one process at a time. For that reason i am using a single semaphore to synchronise my processes. First, i am forking to create 7 children. Then, using a for loop i am calling a function which reads a line from the file and then prints it. If the last reading process is done reading it makes an UP operation which is caught by the last child which writes the last line in the file.

This is my file:

Hello! This is a shared file between processes!

Hello! This is a shared file between processes!

Hello! This is a shared file between processes!

Hello! This is a shared file between processes!

Hello! This is a shared file between processes!

Hello! This is a shared file between processes!

and this is my code:

#include <stdio.h>          /* printf()                 */
#include <stdlib.h>         /* exit(), malloc(), free() */
#include <sys/types.h>      /* key_t, sem_t, pid_t      */
#include <sys/shm.h>        /* shmat(), IPC_RMID        */
#include <errno.h>          /* errno, ECHILD            */
#include <semaphore.h>      /* sem_open(), sem_destroy(), sem_wait().. */
#include <fcntl.h>          /* O_CREAT, O_EXEC          */
#include <sys/mman.h>
#include <unistd.h>
#include <sys/wait.h>

sem_t wrt;

void read_print(FILE *file)
{
    char c[1000];

    fscanf(file, "%[^\n]", c); //reading a single line from the file
    printf("%s\n", c); //and printing it.
}

int main()
{
    FILE *fp;
    int i, counter = 0;
    pid_t pid[7];


    fp = fopen("shared_file.txt", "r+");
    sem_init(&wrt, 1, 1); //initialiing the semaphore to be shared between$


    if(fp == NULL)
    {
            printf("Error opening file!");
     exit(1);
    }

    /* creating the child processes  */
    for(i = 0; i <7; i++)
    {
            pid[i] = fork();

            if(pid[i] == 0)
                    break;
    }

    for(i = 0; i<6; i++)
            if(pid[i] == 0) //if the processes is a child process
            {
                    read_print(fp); //call the function
                    counter++; //increment the process counter by 1

                    if(counter == 6) //if we are at the final process
                            sem_post(&wrt); //UP operation

                    exit(0); //and then exits
            }
     if(pid[6] == 0) //if the final process is a child
     {
            sem_wait(&wrt); //DOWN operation
            fprintf(fp, "...and this is the final line."); //writes a new $
            exit(0);
     }


     fclose(fp); //closes the file.

     return 0;
}
  • It's a bad idea to re-implement `fgets` using `scanf`. – William Pursell Jan 09 '20 at 23:42
  • Consider the first child. When it is running, `pid[0]` is set to zero, but `pid[1]` thru `pid[6]` are uninitialized. Yet that child loops through the array checking all of them. That's not what you meant to do. – William Pursell Jan 09 '20 at 23:44
  • oi....I see how that works. That is pretty convoluted! I'm not convinced it works, but I see what you're trying to do with that loop. Don't do that. – William Pursell Jan 09 '20 at 23:46
  • counter is never going to be 6. I think you are mistakenly thinking that the children are sharing the `counter` variable. Each child has its own copy, and each child increments it to 1. it never gets to 6. – William Pursell Jan 09 '20 at 23:49
  • is there a way to make the counter variable shared between the processes? – Foivos Allayiotis Jan 09 '20 at 23:57
  • and what if instead of a for loop i used 6 separate if statements – Foivos Allayiotis Jan 09 '20 at 23:59
  • Most of the elements of your `pid` array are being read before being initialized, too. It too isn't shared between processes. – Shawn Jan 10 '20 at 00:47
  • If you want data that's shared between processes, use shared memory. But then you'll have to implement a mutex to coordinate access to it (unless the semaphore serializes everything). – Barmar Jan 10 '20 at 01:26

0 Answers0