3

Take a look on this code

int main(int argc, char **argv) 
{
int pid[3];
int i,tmp;
pid[0]=getpid();


if((tmp=fork()) == 0) 
{
    pid[2]=getpid();
    printf("3. PIDY %d %d %d\n", pid[0], pid[1], pid[2]);
}
else
{
    pid[2]=tmp;
    if((tmp=fork()) == 0)
    {
        pid[1]=getpid();
        printf("2. PIDY %d %d %d\n", pid[0], pid[1], pid[2]);
    }
    else
    {
        pid[1]=tmp;         
        printf("1. PIDY %d %d %d\n", pid[0], pid[1], pid[2]);
    }
}
return 0;
}

On the output im getting smth like that:

1. PIDY 101 102 103
2. PIDY 101 102 103
3. PIDY 101 0 103

Im wondering why im getting pid[1] = 0 in 3rd process? Any idea how to fix it?

SirDarius
  • 41,440
  • 8
  • 86
  • 100
  • 1
    It's hard to say how to fix it because the problem is in your expectations. What value did you think it should have, and why? –  May 24 '13 at 10:45

3 Answers3

5

The process that prints the 3. line has already forked off before anything sets pid[1]. It's not in shared memory, so no values can be stored into it from the other processes, and you never initialized it, so it contains memory dirt, only coincidentally 0.

If the array was declared as a global variable or if it were a static in a function, then the elements would have been initialized to 0 unless already initialized. initial value of int array in C would be a good read.

Community
  • 1
  • 1
  • 0 on a fork is no dirt, its the return of `fork()` to distinguish process SON – mf_ May 24 '13 at 10:21
  • Look again, @mf_, only 2 of the processes had a pid assigned there. The other one just has uninitialized memory. –  May 24 '13 at 10:21
  • but process son inherits a copy of fathers contextual memory, including `tmp` in this case, which was filled with 0 from `fork()` return itself – mf_ May 24 '13 at 10:24
  • 1
    @mf_ seriously look closer. There are 2 fork calls. The first one occurs before anything has been assigned to `pid[1]`. That is a local variable with nothing in it. Memory dirt. It stays dirty in the top branch of the outer `if` all the way through to the `printf` –  May 24 '13 at 10:26
  • @user2410128: You can't, at least not without major additional efforts, involving some IPC. At it stands, the observed behaviour is by design. – alk May 24 '13 at 10:58
  • @wumpus-q-wumbley, got it, grandfather doesnt know his grandson unless they comunicate with each other, maybe trough a `pipe()`+doing a `wait(NULL);` before printf ? – mf_ May 24 '13 at 11:18
0

You have to use some sort of signal exchange between the two processes. You may use a pipe or shared memory for complex data or simply signals for simple messages.

urzeit
  • 2,863
  • 20
  • 36
0

i solved problem in this way, much more code but i didnt have any other idea to solve it (i dont have experience with shared memory and pipes) take a look:

FILE * fp;
int pid[3];

void ReadPid()
{ // odczytanie pidow
    fp = fopen("/tmp/pid","r");
    int r=sizeof(int)*3;
    int readed; 
    char * out = (char*) pid;
    while(r>0)
     {
        readed = fread(out,1,sizeof(pid),fp); 
        if(readed!= EOF)
            {
             out+=readed;
             r-=readed;
            }       
     }
     fclose(fp);
}

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

int i,tmp;
fp = fopen("/tmp/pid","w");
if(fp==NULL) err("nie mozna otworzyc pliku /tmp/pid");


if((pid[2]=fork())==0)
{
    ReadPid();
    printf("3. PIDY %d %d %d\n", pid[0], pid[1], pid[2]);
}
else
    if((pid[1]=fork())==0)
    {
        ReadPid();
        printf("2. PIDY %d %d %d\n", pid[0], pid[1], pid[2]);
    }
    else
        if((pid[0]=fork())==0)
        {
            ReadPid();
            printf("1. PIDY %d %d %d\n", pid[0], pid[1], pid[2]);
        }
        else
        {
            fwrite(pid,1,sizeof(pid),fp);
            fclose(fp);
        }

return 0;
}

if u got any other idea, please post it

  • There's a huge unexplained difference between this and the original program - it forks 3 times; the original only forked twice. And there's no hint of the actual problem you're trying to solve except that it involves a few processes that need to know each others' PIDs for some reason. Writing PIDs to temporary files is a satisfactory solution to some problems, but your code does it badly. There's no guarantee that the writer finishes writing before the readers start reading. Also, the process that writes its PID is the parent of the others, so they could just use `getppid` instead. –  May 24 '13 at 21:18
  • Actually I withdraw the last part of the previous comment. I didn't notice that you are writing the whole pid array to the file. But the other problem remains. –  May 24 '13 at 22:23