6 Replies - 2825 Views - Last Post: 09 December 2012 - 12:51 PM Rate Topic: -----

#1 apaddobs  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 49
  • Joined: 16-May 12

Forked process writing to a global variable

Posted 07 December 2012 - 06:00 PM

I have the following piece of code :

for (int i = i; i < xprocs; i++) {
    pid = fork ();
    if (pid == 0)
        func ();
}

void func ()
{
    static error = 0;
    while (do something) {
         if (something goes wrong)
              error ++;
     }
}



So each forked process will have its own "error" variable that starts with the counter 0 and have one final value.

At the end of all the processes, I want to know the total number of "errors" across the 4 processes. One way is to write out , at the end of func, the value of error to a file (xproc.1, xproc.2, xproc.3 and xproc.4) and read it out from them. That looks a very elementary way of doing things - which will involve opening those many FILE pointers etc.

I know I can have a global variable say n_error; and increment it using semaphores.

void func ()
{
    int semid = sem_getid ("/tmp/abc");
    static error = 0;
    while (do something) {
         if (something goes wrong) {
              sem_wait (sem_id);
              n_error ++;
              sem_post (sem_id);
     }
}



But I want these processes to be exclusive to each other - and not spend time in acquiring and releasing the semaphore lock.

So the question I have is, if my func is actually doing a lot of stuff with "n" numbers in parallel, would adding a semaphore slow things down a bit - especially if "n" is a large number?

Am I better off having a map wherein
map [xproc1] = nerror;
map [xproc2] = nerror;

i.e., different processes will only modify the value corresponding to their key. I do understand that the map object, as such, is just one. But could there be a possibility of something getting corrupted in the map because of the race condition?

Is This A Good Question/Topic? 0
  • +

Replies To: Forked process writing to a global variable

#2 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1102
  • View blog
  • Posts: 4,597
  • Joined: 09-June 09

Re: Forked process writing to a global variable

Posted 08 December 2012 - 04:57 PM

When you fork, the entire process is copied - including the global variables. There will not be a shared global variable between your processes. You could set up a shared memory segment between the processes and use semaphores; however thats overkill. I would create a simple message handler by establishing a single pipe which all of the children write to. The parent process of all the children will then sit around an wait for error messages.

i.e.

#include <stdio.h>
#include <unistd.h>

#define NUM_CHILDREN 5

void childProc(int id) {
   int i=0;
   for(; i<10000; i++); //some dummy work
   printf("An error occured in child %d\n", id);
}
int main() {
   int fd[2];
   int i=0;
   int pid;
   int errorCount = 0;
   char errorMsg[100];

   pipe(fd); //create single pipe

   //spawn off 5 children
   for(; i < NUM_CHILDREN; i++) {
      if((pid = fork()) < 0)
         fprintf(stderr, "Fork error");
      else if(pid == 0) {
         dup2(fd[1], 1); //redirect stdout to our pipe fd
         close(fd[0]); 
         close(fd[1]);
         childProc(i); //do child function
         return 0;
      }
   }
   
   dup2(fd[0], 0); //redirect stdin to our pipe fd
   close(fd[1]);
   close(fd[0]);

   //wait for errors
   while(fgets(errorMsg, 100, stdin) != NULL) { //wait for child errors
      errorCount++;
      printf("%s", errorMsg); //prints to console
   }
   
   printf("Total Errors = %d\n", errorCount);
   return 0;
}



This post has been edited by jjl: 08 December 2012 - 04:58 PM

Was This Post Helpful? 0
  • +
  • -

#3 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 680
  • View blog
  • Posts: 2,357
  • Joined: 31-December 10

Re: Forked process writing to a global variable

Posted 09 December 2012 - 09:24 AM

You should ALWAYS check the return values from system calls and also the value of errno if there is an error. Also, you only put a very minimum of comments explaining what's going on. For example, in both the children and the parents, why do you close the file descriptors for both ends of the pipe? I know this is correct, but there are reasons for why you close both of them and you don't explain why.
Was This Post Helpful? 0
  • +
  • -

#4 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1102
  • View blog
  • Posts: 4,597
  • Joined: 09-June 09

Re: Forked process writing to a global variable

Posted 09 December 2012 - 10:11 AM

Quote

You should ALWAYS check the return values from system calls and also the value of errno if there is an error.

Yes, in industry; however, I am a little loose on that subject when I am whipping up some 5-min code.

Quote

Also, you only put a very minimum of comments explaining what's going on.

There are a sufficient amount of comments, I am not writing a tutorial on the subject.
Was This Post Helpful? -1
  • +
  • -

#5 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 680
  • View blog
  • Posts: 2,357
  • Joined: 31-December 10

Re: Forked process writing to a global variable

Posted 09 December 2012 - 11:40 AM

View Postjjl, on 09 December 2012 - 12:11 PM, said:

There are a sufficient amount of comments, I am not writing a tutorial on the subject.

You're writing an answer to someone asking a question, if you're not going to fully answer it, then why answer any of it at all? Just answer me this, in the child processes, why are both ends of the pipe closed?

This post has been edited by vividexstance: 09 December 2012 - 11:40 AM

Was This Post Helpful? 0
  • +
  • -

#6 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1102
  • View blog
  • Posts: 4,597
  • Joined: 09-June 09

Re: Forked process writing to a global variable

Posted 09 December 2012 - 12:27 PM

Quote

You're writing an answer to someone asking a question, if you're not going to fully answer it, then why answer any of it at all?


The original question is below - notice how it has nothing to do with the close or dup2 system functions.

Quote

So the question I have is, if my func is actually doing a lot of stuff with "n" numbers in parallel, would adding a semaphore slow things down a bit - especially if "n" is a large number?


I suggested a different route of IPC by using pipes - both with a text explanation and a code example. The details of how dup2 are not in the original question, and if he is confused on why both ends of the pipe are being closed, then he will ask a question himself. I am not going to assume that he as a question about every line of code.

Quote

ust answer me this, in the child processes, why are both ends of the pipe closed?

If you really don't know, then you should of started your own topic instead of hijacking this one.

The child does not need to read from the pipe, therefore you close fd[0]. dup2 copies the write file descriptor of the pipe to the stdout file descriptor. Since stdout refers to the write end of the pipe, you can close fd[1].

This post has been edited by jjl: 09 December 2012 - 12:28 PM

Was This Post Helpful? 0
  • +
  • -

#7 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 680
  • View blog
  • Posts: 2,357
  • Joined: 31-December 10

Re: Forked process writing to a global variable

Posted 09 December 2012 - 12:51 PM

I know what pipes are, I wasn't asking for my benefit. You assume the OP knows about pipes, all I was suggesting was to comment all non-trivial code.

Just because your code compiles, doesn't mean there are no bugs in it. What happens of fork() fails?

This post has been edited by vividexstance: 09 December 2012 - 12:53 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1