From: alsaggaf@athena.mit.edu (M. Saggaf)
Subject: [SUMMARY] Can a process have access to a parent's variable?
Organization: Massachusetts Institute of Technology
Date: Wed, 7 Oct 1992 04:31:59 GMT

In article <1992Oct6.035638.5981@athena.mit.edu> alsaggaf@athena.mit.edu (M. Saggaf) writes:
>If a proceess forks a child, can the child process have access to one
>or more of the parent's variables (assume global variables)? In other
>words, suppose the child process wants to know what the parent has
>done to the value of a certain variable since the time the child
>process was forked. How can it do that? If that's not possible, what
>form of inter-process communications can be used?
>
>Please send e-mail. I'll summarize if I receive responses.
>

Thanks to all those who reponded to my question about inter-process
communications. It seems that the easiest way to do it (and the way I
did it) is to use pipes. Look at the man pages of pipe(2), write(2)
and read(2) to see how it is done. Another way would be to use
sockets, and a third one to use shared memory, although the latter is
not available on all Unix platforms (apparently can be done in systems
like SYSV with IPC). 

As I promised, here is an edited summary of the responses I got, sorted
by date received. I didn't omit anything other than the unneccessary stuff
(and one letter basically said 'you should have asked that elsewhere').
Again, thanks for your kind letters.

Floyd Davidson <floyd@ims.alaska.edu> writes:
You do in fact need inter-process comm of some kind.  The simple ones
are named pipes, signals (check out USRSIG1 and USRSIG2), and shared
memory segments.  psuedo tty's and other things are available depending
on what kind of an OS you have.

adrian@remus.rutgers.edu writes:
   So far as I know, there's no way to do what you're asking, but there are
ways to do similar things. Since fork() generates a new process, the variable
memories are duplicated. No luck there. You can however try using shared
memory, or one of the other forme of IPC. it depends on what UNIX you're using.
(Presuming that you're using UNIX at all). If you are using UNIX, poke around
in the section 2 manpages, starting with `man 2 Intro'. This should point you
in the right direction.

jlnance@eos.ncsu.edu writes:
I dont think that this can be done under UNIX.  SVR4 may provide facilities for
this, but I am not sure.  The easyiest way to talk between processes, is to
call pipe() (I think) before you fork.  Then you will have a pipe between the
processes after you fork.

pjames@hubcap.clemson.edu (perry r james) writes:
Hi,
   The only way the two processes can tell what the other is doing/has
done is to communicate.  They can do this through a file (messy) or 
directly through pipes.  Here is some code that does a consumer/producer
routine.
   I hope it is of some help.
   have fun,
   perry
   pjames@hubcap.clemson.edu

/**********************
 producer/consumer 
**********************/

#include <stdio.h>

int pipe1[2];
int pipe2[2];
int pipe3[2];

void reader(void);
void writer(void);
void squish(void);
void child(void);

main()
{
    int pid;

    pipe( pipe1);
    pipe( pipe2);

    pid = fork();
    if (pid==0)
    {  child();
    }else
    {  reader();  /* this is what the parent is to do */ 
    }
}

void child()
{
    int pid;

    pipe( pipe3 );
    pid = fork();
    if (pid ==0) 
    {  squish();  /* this is the grandchild of the first process */
    }else
    {  writer();  /* this is the "middle" process */
    }
}

void reader()
{
    char c;
    int  i;

    while (1)
    {     for (i=0; i<10; i++)
          {   read( 0, &c, 1);
              if (i==0 && c=='?')
              {  write( pipe1[1], &c, 1);
                 return;
              }
              if (c=='\n') c='$';
              write( pipe1[1], &c, 1);
          }
    }
}

void squish()
{
    char c, c2;

    while (1)
    {    read( pipe1[0], &c, 1 );
         if (c=='?')
         {  write( pipe3[1], &c );
            return;
         }
         if (c=='*')
         {  read( pipe1[0], &c2, 1 );
            if (c2=='*')
               c = '@';
            else
            {  write( pipe3[1], &c, 1 );
               c = c2;
            }
         }
         write ( pipe3[1], &c, 1 );
    }
}

void writer()
{
    char c;
    int  i; 
 
    while (1)
    {   for (i=0; i<12; i++)
        {   read( pipe3[0], &c, 1 );  
            if (c=='?') return;
            write( 1, &c, 1 );
        }
        printf("\n");
       
    }
}

-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
with this input file

123456789
abcdefghi
**hello**
#**dd*d*d
?

this output is produced

123456789$abcdefghi$@hello@$#@dd*d*d$

berlin@is.morgan.com (Alexander Berlin) writes:
Since you mention fork(), I assume you are interested in UNIX.
The easiest way is to use shared memory. In environment that supports threads
or light weight processes it is as simple as you put it in your question -
you just refer to exactly same variable since threads share adress space with
the parent(main thread).

jxh@math.ksu.edu (James C. Hu) writes:
This clearly could have been answered by someone in your neck of the
woods.  If you are dealing with a UNIX system, you have to use some
sort of IPC (Inter-Process Communication) mechanism.  This is either a
file, pipe or shared memory.  Which is better depends on how much the
child wants to know and how often the child wants to know it.

"Richard A. Stroobosscher" <rastroob@watcgl.uwaterloo.ca>
In a a system that support shared memory, you will be able to set
up a region of memory shared by parent and child.  You will find this
ability on machines built by sequent (man cc), some sgi machines 
(man sproc) and some sun machines (man shmctl).

If no shared memory is available, you can use sockets (man socket) to
communicate between processes, or more simply, a threads package.

pckim@dbserver.kaist.ac.kr (Pyung-Chul Kim) writes:
As you might see, fork(2) copies the data/stack segments of the parent
to the child process image. This implies that the child process can
inherit all status of the parent at fork(2), but there is no way to
peek the parent process's image after forked.
You may need to use interprocess communication such system V IPC,
pipes or socket. If you are trying to make things simple, I'd
recommend pipe(2). But, I think the most efficient way is
to use IPC shared memory facility. That is, you can place
the parent variables to be shared by child in the shared memory so
that the child process can attach the memory region to its address
space and access it. For more details, please refer to manual.

Maybe, you're more interested in light-weight process, thread
and something like those to solve your problem.
For this, you may need to think about carefully whether you
really need Unix process (I mean, fork(2)-ed process) separation
or just separation of flow (thread).

francis@Galois.NSCF.Org (John Stracke)
The child cannot get at the parent's variables.  The data space is
copied and split off at fork() time.  What you should do is open a
pipe (maybe two, so you can have bidirectional comm) before fork()ing.
Pipes are useable only when you have a family relationship among
processes, as in this case; when they are, they're the most portable
IPC there is.  (The Unix which doesn't have the pipe() call is not the
true Unix.) They're also easy to use, and faster than sockets.

mjd@saul.cis.upenn.edu (Mark-Jason Dominus)
Again, depending on your operating system, some form of shared memory,
pipes, messages, or semaphores may be available, or they may not. The
most portable method is to have the parent write the information to a
file, and have the child read it back.  Under UNIX, a pipe may be a
better solution.

smclewin@ultrix.ramapo.edu (Scott M McLewin)
This works only for allocated memory, not automatic variables.  Take
the pointer to the memory, sprintf() it into a string, and pass it to 
the child process either as a command line parameter, or in the 
environment.  Have the child process convert the string back into
a pointer, and access the memory.  

Just thinking about it, this method would not work in DOS's small/compact
or medium memory models.  The pointer would have to be an absolute address.
As far as Unix is concerned, I have no idea if pointers are relative or
absolute.




--
/M. Saggaf
 alsaggaf@athena.mit.edu