0

First of all, I surely know there are faster and less overkill solutions to this, but I absolutely need to fill in an array with child processes only.

Let's say I have 3 childs:

   int pos = 0; 
   for (i = 0; i<3 ; i++){
switch (fork()){

    case -1: //fork error;
        printf("[ERROR] - fork()\n");
        exit(EXIT_FAILURE);

    case  0: //child
        fill(&req, pos);
        pos++;
        exit(EXIT_SUCCESS);

    default:
        break;
}

}

where fill basically works like this:

   void fill (request *req, int pos){
     req->array[pos] = 1;
    }

I realized this method of course doesn't work, since every child has a copy of pos = 0, and they just increment their copy, so the array always gets modified at 0. The struct request is a simpe struct with a pid and a int array to send through fifo.

  typedef struct request {
  int cpid;        //client pid
  int array[SIZE]; //array
  } request;

What can I do to fill in this array with the child processes only? I have to repeat, I can't use workarounds, just fork() and childs. Thanks!

edornd
  • 441
  • 1
  • 4
  • 18
  • You're aware that a forked process doesn't share memory with the parent or any of its siblings? – Art Aug 28 '14 at 09:15
  • Yes, as I wrote after fill method, I realized in this way is impossible since they copy the pos value. – edornd Aug 28 '14 at 09:17
  • 1
    You "absolutely need to" use a mechanism that can not do what you want (at least not without a large amount of very system specific setup). Why? What's the point? Did someone give you a hammer and ask you to only use it to polish a window? I don't understand the question at all. The answer is: "you can't do that, as you've already figured out yourself". – Art Aug 28 '14 at 09:23
  • 1
    Well, I just follow instructions, that clearly say that the client have to fork (2,3,4 or 6 times) and add an element to the request. If I knew a solution I wouldn't have asked. – edornd Aug 28 '14 at 09:37
  • what is `request` here? is it structure? – Sathish Aug 28 '14 at 09:40
  • Yes it is. I added the general struct def... – edornd Aug 28 '14 at 09:50
  • Perhaps share your request data: http://stackoverflow.com/questions/5656530/how-to-use-shared-memory-with-linux-in-c – dragosht Aug 28 '14 at 09:55

2 Answers2

1

If the children are the ones who have to fill the array, then their modifications cannot be seen by the parent or by any other child, unless the parent and the child share some memory (shmget).

Other workarounds include sending all the data to a central process using pipes or any other communication mechanism.

Juan Cespedes
  • 1,299
  • 12
  • 27
0

You cannot alter some data (to be shared) after a fork, because each process has -by definition- its own address space, hence any changes to data is private to that process (unless you use shared memory).

You could use shared memory, which you have to set up before the call to fork(2). Then you have synchronization issues. So read shm_overview(7) and sem_overview(7); in your case, I feel it is overkill.

You might also use threads, not processes. Some processes have several threads, all sharing -by definition- the same common address space. Again, synchronization is an issue (e.g. with mutexes). Read some pthread tutorial

You could use some other IPC, e.g. pipe(7)-s. You'll probably want a multiplexing syscall like poll(2).

(I guess, perhaps incorrectly, that the whole point of this homework is to teach you about pipes and event loops; if you use pipes, better adopt some textual protocol)

Read Advanced Linux Programming.

BTW, on fork and other syscalls error, you generally should call perror(3) -not a plain printf like you do- then exit(EXIT_FAILURE).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Your guess it's kind of right, it's a project about IPC and Unix in general. Definitely going for shm and sems. Thanks for the tip about errors, this was just a piece of code, in future I will surely need error handlers. – edornd Aug 28 '14 at 12:31