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

  • From: Tyler Littlefield <tyler@xxxxxxxxxxxxx>
  • To: programmingblind@xxxxxxxxxxxxx
  • Date: Fri, 18 Dec 2009 12:32:17 -0700

Looks like I had that reversed, but I have the idea, anyway. fork returns the 
child pid in the parent process--which actually makes sense. So I can easily 
set up my data structure for transmitting data back and forth between processes 
and use a pipe to do so, which should be more elegant than a connected socket I 
believe.

On Dec 18, 2009, at 11:14 AM, Tyler Littlefield wrote:

> o, I got it! So, fork in the parent process returns 0, while it returns the 
> pid in the child process?
> On Dec 18, 2009, at 10:48 AM, Jared Wright wrote:
> 
>> 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
> 
> __________
> 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: