0

my code will receive 2
1st - The number of children from fork
2nd - Name of a file

So each process (parent and its children), should read the file, print on screen. Just that, pretty much simple, but both children prints its name at the same time.

My code is:

/**********************************************************************************:
 * Filename: dailyAug8.c

  Author: --------

  Description: Daily assignment that shoul receive from command line the 
number of processes and a filename, so that much processes should read the file

  Date Modified:  8/08/20014  

    - File Created 

*************************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>

static sem_t memLock;

/*************************************************************************************
 *    Name:  readFile 
 *     Description: reads each character from the file with the name passde by parameter
 *          
 *   Input: filename - the name of the file 
 *   Output: NULL
 *                                   *************************************************************************************/ 
void *readFile(char *fileName){
    FILE *fp = fopen(fileName,"r");
    char ch;

    if(fp){
        while((ch = fgetc(fp)) != EOF){
            printf("%c",ch);
        }
        printf("\n");
    }else{
        perror("File does not exist.");
    }

    return NULL;
}

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

    if(argc != 3){
        perror("Different number of parameters than expected\n");
    }
    int pid,i;
    char *filename = argv[2];
    int numberOfProcesses = strtol(argv[1],NULL,10);

    sem_init(&memLock,0,1);
    for(i = 1; i < numberOfProcesses; i++){
        pid = fork();

        if(pid == 0){//It's a child
            sem_wait(&memLock);
        printf("I'm child %d and i will read the %s file\n",i,filename);
            readFile(filename);
        sem_post(&memLock);
            exit(0);
        }else if(pid == -1){    //Something happened and cannot fork
          perror("Can not fork");
        }
  }

  for(i = 1; i < numberOfProcesses; ++i){//Waiting for all the children
      wait(NULL);
  }
  sem_destroy(&memLock);
  printf("I'm the parent and i will read the %s file\n",filename);
  readFile(filename);

  return 0; 
}

the file just have:

lalalalalalal
kakakakaakka
zazazazazaza

the output is:

I'm child 1 and i will read the test file
I'm child 2 and i will read the test file
lalalalalalal
kakakakaakka
zazazazazaza

lalalalalalal
kakakakaakka
zazazazazaza

I'm the parent and i will read the test file
lalalalalalal
kakakakaakka
zazazazazaza
Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
Myrium
  • 205
  • 3
  • 11

2 Answers2

1

Your processes are reading the file simultaneously because you passed a 0 to sem_init for the pshared argument, which means that each process gets its own semaphore and none of them block the others. A pshared argument of 0 tells the call to set up a semaphore that is shared between THREADS but is explicitly not shared between processes. To get it to set up the semaphore in shared memory (memory where forked processes can see it) you need to pass a nonzero value to sem_init.

Take a look at the sem_init man page

Sniggerfardimungus
  • 11,583
  • 10
  • 52
  • 97
1

The problem is sem_init creates semaphore on the stack of the parent process, and is copied when forked. The key is to create it in a region of shared memory.

Try sem_open instead:

http://linux.die.net/man/3/sem_open

See here for a nice example:

http://www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html?page=5


Also, found this:

sem_init on OS X

It appears that sem_init isn't properly implemented on Mac OS X.

Community
  • 1
  • 1
skarist
  • 1,030
  • 7
  • 9