Linux / Perl - What happens when a process is forked?

5

I've read about fork and from what I understand, the process is cloned but which process? The script itself or the process that launched the script?

For example:

I'm running rTorrent on my machine and when a torrent completes, I have a script run against it. This script fetches data from the web so it takes a few seconds to complete. During this time, my rtorrent process is frozen. So I made the script fork using the following

my $pid = fork();
if ($pid) == 0) { blah blah blah; exit 0; }

If I run this script from the CLI, it comes back to the shell within a second while it runs in the background, exactly as I intended. However, when I run it from rTorrent, it seems to be even slower than before. So what exactly was forked? Did the rtorrent process clone itself and my script ran in that, or did my script clone itself? I hope this makes sense.

somebody

Posted 2010-03-07T00:49:14.437

Reputation: 93

Your probably better off asking on Stackoverflow. – Unfundednut – 2010-03-07T00:59:49.960

1rTorrent may have setup pipes for its child's std{in,out,err}. If so, you might need to close them (or close and repoen the output descriptors to some log file, if that is important) before rTorrent will continue. – Chris Johnsen – 2010-03-07T04:09:45.737

Answers

3

From Advanced Programming in the UNIX Environment by W. Richard Stevens (pg. 188):

8.3 fork function

The only way a new process is created by the Unix kernel is when an existing process calls the fork function. (This doesn't apply to the special processes that we mentioned in the previous section—the swapper, init, and pagedaemon. These processes are created specially by the kernel as part of bootstrapping.)

#include <sys/types.h>
#include <unistd.h>

pid_t fork(void);
/* Returns: 0 in child, process ID of child in parent, -1 on error */

The new process created by fork is called the child process. The function is called once but returns twice. The only difference in the returns is that the return value in the child is 0 while the return value in the parent is the process ID of the new child. The reason the child's process ID is returned to the parent is because a process can have more than one child, so there is no function that allows a process to obtain the process IDs of its children. The reason fork returns 0 to the child is because a process can have only a single parent, so the child can always call getppid to obtain the process ID of its parent. (Process ID 0 is always in use by the swapper, so it's not possible for 0 to be the process ID of a child.)

Both the child and parent continue executing with the instruction that follows the call to fork. The child is a copy of the parent. For example, the child gets a copy of the parent's data space, heap, and stack. Note that this is a copy for the child—the parent and child do not share these portions of memory. Often the parent and child share the text segment (Section 7.6), if it is read-only.

On Linux, Perl's fork operator calls the system's fork and returns undef on failure rather than -1.

Stevens gives lists (pg. 192) of inherited properties and differences between parents processes and their forked children:

Besides open files, there are numerous other properties of the parent that are inherited by the child:

  • real user ID, real group ID, effective user ID, effective group ID
  • supplementary group IDs
  • process group ID
  • session ID
  • controlling terminal
  • set-user-ID flag and set-group-ID flag
  • current working directory
  • root directory
  • file mode creation mask
  • signal mask and dispositions
  • the close-on-exec flag for any open file descriptors
  • environment
  • attached shared memory segments
  • resource limits

The differences between the parent and child are

  • the return value from fork
  • the process IDs are different
  • the two processes have different parent process IDs—the parent process ID of the child is the parent; the parent process ID of the parent doesn't change
  • the child's values for tms_utime, tms_stime, tms_cutime, and tms_ustime are set to 0
  • file locks set by the parent are not inherited by the child
  • pending alarms are cleared for the child
  • the set of pending signals for the child is set to the empty set

Greg Bacon

Posted 2010-03-07T00:49:14.437

Reputation: 813