Re: question: spawning processes in a unix c++ application

  • From: Jared Wright <wright.jaredm@xxxxxxxxx>
  • To: programmingblind@xxxxxxxxxxxxx
  • Date: Fri, 18 Dec 2009 12:48:08 -0500

The switch statement is to keep your parent process from executing unwanted instructions after the fork is made. Although I thought process ID = 0 was the child process which is the reverse of what Laura's code indicates, but it's been a while since I've had to play with this sorta stuff. Either way, instructions after a fork call would be executed by both processes unless some control mechanism like this is used.



Jared

On 12/18/2009 11:33 AM, Tyler Littlefield wrote:
Hello laura,
thanks for the info, this really helps clarify things; I have a couple of 
questions.
 From what I understood, pipe creates an array of two dementions, 0 is input 
and 1 is output or however you decide to use them. so, couldn't you just send 
data to 0 and it would end up on the output end of the pipe?
Second, I don't really understand what your fork statement there does. I know 
fork spawns another process, but I'm not quite sure what the whole case 0: 
//parent process
bit was about. If you fork your going to be in the child process, no?

Thanks,
On Dec 18, 2009, at 8:46 AM, qubit wrote:

Hello Ty -- back on unix again?
As long as you are on the same server you can fork an independent process to
do what you want -- of course if you are looking at 2 systems with a network
connection, you wouldn't use fork, but rather start two process manually,
one on each side.

The following took a little time to type... Hmm Hope it is useful to
someone -- maybe I should put it in a tutorial on the website.  I'll see if
there is something about unix software development that hasn't been written
yet and post it.
*******
I have in my possession a game I wrote for my nephew when he was small.  It
consists of a main board process and 5 players -- 4 computer generated
monsters and one human player.  All the monsters were spawned as independent
processes, as was the player.  The only difference between the player
process and the monster processes was that the monsters communicated with
the main board which would send it board state info, and the monster
processes would then submit moves.  The player process only communicated the
users moves to the main board, which assumed the player didn't need the
state information.

Anyway, the seedy little reproductive details of the processes of the game
were as follows (pseudo code):

/* note: pipe returns a tiny array of 2 integer file identifiers.
player_fd[0] is the front of the queue where moves are communicated -- it is
input from the point of view of the main process, so it should be read.
player_fd[1] is the rear of the queue where data is written.
Now if you want to write from child's stdout to be read by the main
process's input at the other end of the pipe, you have to somehow tie stdout
in the child to the rear of the player_fd pipe.  How do you do that? This is
a twisted little trick. The secret is that stdin and stdout and stderr are
in a global space that is inherited by the child process even after it calls
exec.  exec does not overwrite this data. This means that the parent and
child processes can set up any environment it wants, including command line
arguments to main, before calling exec to start the child.
Noe for some pseudo code:*/

// globals in file main.c
//file descriptors associated with player and monsters  -- note, monsters
communicate 2 ways so need 2 descriptors
static int player_fd = -1;
static int monster_fd[4][2] = { { -1, -1}, { -1, -1 }, { -1, -1 },
{ -1, -1 } };

int pid, mid[4]; // process ids of player and monsters

// This function will fork and exec the player process
spawn_player() {
    p = create a pipe -- I forget the syntax
    pid = fork()
    switch (pid) {
    case -1: fatal error
    case 0: // parent process
        // you are in the parent; close dangling end of pipe and return
        close(p[1]);
        player_fd = p[0];
        // note that rear of pipe is duplicated in the child process and the
id will not be used by the parent process, so we close it.
        return
        default: // you are in a new process with process id == pid.
        // set up pipe the way you need it before exec
        // Note: stdin, stdout and stderr have file descriptors of 0, 1 and
2 in all new processes.
        // When you close stdout, you are freeing up number 1 to be used in
the next file allocated -- in this case, the dup operation will set stdout
to be the rear of the pipe.
        close(1) // stdout's process id
        dup(p[1]) -- this will allocate a new file 1 (stdout that will point
to the rear of the pipe)
        close( p[0]) close(p[1]); // these are duplicates that hang onto
resources.
        exec("player"...)
    }
}

I'll leave it as an exercise to write the spawn_monster function.
Be sure to keep straight the nitty little differences between the ends of
the pipe -- pipe[0] is always front, pipe[1] is always rear.
Also keep process ids distinct from file ids.
Hint: monsters need 2 pipes instead of one -- there is the move pipe where
the monster writes info to the main process, and the info pipe which is used
by the main process to send info to the monster.
.

Please reply with questions and I'll compile this with other things to post,
if needed.
Happy hacking.
--le

----- Original Message -----
From: "Tyler Littlefield"<tyler@xxxxxxxxxxxxx>
To:<programmingblind@xxxxxxxxxxxxx>
Sent: Thursday, December 17, 2009 11:52 PM
Subject: question: spawning processes in a unix c++ application


Hello all,
I understand the basics of how fork works, but here's what I'm trying to do;
maybe someone can give me a bit of a push in the right direction.
I have a server that will be working with two interfaces, a telnet interface
and a web interface. The telnet interface being part of the mud is already
built in, but I would like to add in a web interface that would allow for
viewing of generated data.
What my idea was, was this:
I want to somehow create a pipe that will allow for me to transport data
back and forth between the server. I don't see why I should need to create
two separate applications to serve one purpose, I would like to somehow
spawn a new process from within the main server that will allow me to keep
the pipe open and send/receive requests through it. Basically the server
will send the data, and the web interface will generate the data, which will
remove a lot of work off the mud its self.
Can this forking easily be accomplished? I assume I could open the pipe and
then fork from within a web initialization function toward the top of the
code and then wait for a signal through the pipe to notify the web server
that it can start the listening process, but I'm not quite sure how all this
would work.

Thanks,

Tyler

__________
View the list's information and change your settings at
//www.freelists.org/list/programmingblind

__________
View the list's information and change your settings at
//www.freelists.org/list/programmingblind
__________
View the list's information and change your settings at
//www.freelists.org/list/programmingblind


__________
View the list's information and change your settings at //www.freelists.org/list/programmingblind

Other related posts: