RE: question: spawning processes in a Unix c++ application


Tyler I would suggest you get beginning Linux programming.  It's a very good
book in c++ if you can't find a very good copy drop me a personal mail.  Oh
and don't take the beginning word wrong it is a very good book that goes
into socket programming and all kinds of Unix stuff you seem to need forking
included.  Oh and another good place to go is the socket page on line I
don't remember what it is called but if you search for Linux sockets I am
sure you will find it.

  

Ken

-----Original Message-----
From: programmingblind-bounce@xxxxxxxxxxxxx
[mailto:programmingblind-bounce@xxxxxxxxxxxxx] On Behalf Of Tyler
Littlefield
Sent: Friday, December 18, 2009 8:13 PM
To: programmingblind@xxxxxxxxxxxxx
Subject: Re: question: spawning processes in a Unix c++ application

fudge? The ultimate brain food, apart from pizza; that's still at the top.
I'm not understanding all this closing. Naturally I'll close stdin stdout
and stderr in the child because I don't need them, but with a pipe I would
have [0] for input and [1] for output on the parent, and [0] for output and
[1] for input on the child, no? That would allow me to do both input and
output from what I understand, which I need.

On Dec 18, 2009, at 5:51 PM, qubit wrote:

> PS:  I have somewhat more to say, Tyler and anyone else who wants to
listen, 
> about the file descriptor numbers and the way files -- including special 
> files like pipes -- are handled.  First, after a successful fork, the
parent 
> has all the same open files, which includes the pipe (containing 2 file 
> descriptors) and all the stdio files.
> However, what you don't see is that the child process gets all these open 
> files as well -- so if you wanted them to, both the parent and child could

> use all 5 of these file descriptor as if it was the parent.  The
difference 
> is that file descriptors are actually just indexes into a file table, and 
> every time a new file F is opened -- such as when a fork is executed and
the 
> copies of the parent's files are duplicated, the operating system will
bump 
> a counter of the number of file descriptors pointing to F.  When the 
> reference count is 0, F will be closed. (Note that the close function 
> doesn't always close a file; it decrements the reference count and if 0 it

> closes the file.)
> 
> so before the fork, if P and C are the parent and child processes, P will 
> contain 5 open file descriptors -- stdin, stdout, stderr, and the 2 fd's
for 
> the pipe.
> After the fork, P will be the same, but C will have duplicated all the
file 
> descriptors by bumping the reference counts of the already open files.
> 
> So in P, after the fork, you want the front of the queue so you just close

> the rear file descriptor of the pipe.  The child does not close this file 
> descriptor as it will be writing to it.  But it doesn't need the front of 
> the pipe, so it closes that. The OS will recognize it as being tied to a 
> pipe.
> 
> Now the operation using dup()
> 
> the dup function takes an integer file descriptor and opens another file 
> pointing to that underlying file. The OS recognizes when it is working
with 
> a pipe.
> So if you close(1), you are closing stdout  -- and why would you want to
do 
> that? If you immediately follow this with a call to dup(p[1]), the OS will

> search for file free slots in the file table, and stdout is the first it 
> will find.  Now both stdout and p[1] are pointing to the same file 
> descriptor, the rear of the pipe.
> So close p[1] as you won't be using it.  In fact, you don't need the pipe
at 
> all, so if it hasn't been closed in the parent before the fork, close it 
> here.
> Then the child C is ready to call whatever version of exec() it needs in 
> order to invoke the program it wants to run.
> 
> I hope this makes sense.  In fact, if you can pick holes in it, feel free.
> 
> Now back to that xml manual.
> Or maybe another piece of fudge instead...*yum*
> 
> Happy hacking
> ----- Original Message ----- 
> From: "Ken Perry" <whistler@xxxxxxxxxxxxx>
> To: <programmingblind@xxxxxxxxxxxxx>
> Sent: Friday, December 18, 2009 5:11 PM
> Subject: RE: question: spawning processes in a Unix c++ application
> 
> 
> 
> 
> The reason for the case statement is you are in both the child and the
> parent process.  If you look at it this way that as soon as it hits that
> fork statement your code file becomes two identical code files.  One is
set
> to 0 and one is set to 1 so the logic then goes on from there.  As for the
> pipe you need to be able to send on one pipe and receive on the other so
you
> don't get in some kind of grid lock which is why she told you to do it
that
> way.  1 is a pipe and 0 is a pipe so you have to know that the child will
> send on one and receive on the other and visa versa on the parent.
> 
> 
> Now with that all said you don't really need to do any of this.  If your
> already running a mud what you can do is have the web service telnet in
and
> send a special character set that says I am a web server.  From then on
you
> deal with that descriptor different.  Instead of sending straight text you
> can wrap it in xml.
> 
> Now there is another way to do this as well.   If you were using a
database
> as your file system you could pull the information straight from the
> database rather than interacting with the socket code.  So you could use
> something like php to pull from the database.  I am guessing you are
wanting
> to put player stats, clan info and things of the like so that could be
done
> all by database calls.
> 
> Ken
> -----Original Message-----
> From: programmingblind-bounce@xxxxxxxxxxxxx
> [mailto:programmingblind-bounce@xxxxxxxxxxxxx] On Behalf Of Tyler
> Littlefield
> Sent: Friday, December 18, 2009 11:34 AM
> To: programmingblind@xxxxxxxxxxxxx
> Subject: Re: question: spawning processes in a unix c++ application
> 
> 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
>> http://www.freelists.org/list/programmingblind
>> 
>> __________
>> View the list's information and change your settings at
>> http://www.freelists.org/list/programmingblind
> 
> __________
> View the list's information and change your settings at
> http://www.freelists.org/list/programmingblind
> 
> __________
> View the list's information and change your settings at
> http://www.freelists.org/list/programmingblind
> 
> __________
> View the list's information and change your settings at 
> http://www.freelists.org/list/programmingblind

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

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

Other related posts: