p1->p2->p3
By using p1, if you want to kill entire p1,p2 and p3 then we can look into process group. Remember that linux kill command has a option to send signals to entire process group like this :
kill -s sig_num
Also, if you want to start a process through a cgi script and detach it completely from httpd process this would be helpful.
A small program to showcase the use of POSIX setsid.
use POSIX qw(setsid);
chdir '/' or die "Can't chdir to /: $!";
umask 0;
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
#open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>/dev/null' or die "Can't write to /dev/null: $!";
defined(my $pid = fork) or die "Can't fork: $!";
exit if $pid;
setsid or die "Can't start a new session: $!";
while(1) {
sleep(5);
print "Hello...\n";
}
Further details on the process groups ...
Process Groups and Tty Management
One of the areas least-understood by most UNIX programmers is process-group management, a topic that is inseparable from signal-handling.
To understand why process-groups exist, think back to the world before windowing systems.
Your average developer wants to run several programs simultaneously -- usually at least an editor and a compilation, although often a debugger as well. Obviously you cannot have two processes reading from the same tty at the same time -- they'll each get some of the characters you type, a useless situation. Likewise output should be managed so that your editor's output doesn't get the output of a background compile intermixed, destroying the screen.
This has been a problem with many operating systems. One solution, used by Tenex and TOPS-20, was to use process stacks. You could interrupt a process to run another process, and when the new process was finished the old would restart.
While this was useful it didn't allow you to switch back and forth between processes (like a debugger and editor) without exiting one of them. Clearly there must be a better way.
The Berkeley Approach
The Berkeley UNIX folks came up with a different idea, called process groups. Whenever the shell starts a new command each process in the command (there can be more than one, eg "ls | more") is placed in its own process group, which is identified by a number. The tty has a concept of "foreground process group", the group of processes which is allowed to do input and output to the tty. The shell sets the foreground process group when starting a new set of processes; by convention the new process group number is the same as the process ID of one of the members of the group. A set of processes has a tty device to which it belongs, called its "controlling tty". This tty device is what is returned when /dev/tty is opened.
Because you want to be able to interrupt the foreground processes, the tty watches for particular keypresses (^Z is the most common one) and sends an interrupt signal to the foreground process group when it sees one. All processes in the process group see the signal, and all stop -- returning control to the shell.
At this point the shell can place any of the active process groups back in the foreground and restart the processes, or start a new process group.
To handle the case where a background process tries to read or write from the tty, the tty driver will send a SIGTTIN
or SIGTTOU
signal to any background process which attempts to perform such an operation. Under normal circumstances, therefore, only the foreground process(es) can use the tty.
The set of commands to handle process groups is small and straightforward. Under BSD, the commands are:
int setpgrp(int
process_id, int
group_number);
- Move a process into a process group. If you are creating a new process group the group_number should be the same as process_id. If process_id is zero, the current process is moved.
int getpgrp(int
process_id);- Find the process group of the indicated process. If process_id is zero, the current process is inspected.
int killpgrp(int
signal_number, int
group_number);
- Send a signal to all members of the indicated process group.
int ioctl(int
tty, TIOCSETPGRP, int
foreground_group);
- Change the foreground process group of a tty.
int ioctl(int
tty, TIOCGETPGRP, int *
foreground_group);
- Find the foreground process group of a tty.
int ioctl(int
tty, TIOCNOTTY, 0);
- Disassociate this process from its controlling tty. The next tty device that is opened will become the new controlling tty.
The POSIX Approach
The BSD process-group API is rarely used today, although most of the concepts survive. The POSIX specification has provided new interfaces for handling process groups, and even overloaded some existing ones. It also limits several of the calls in ways which BSD did not.
The POSIX process-group API is:
int setpgid(int
process_id, int
process_group);
- Move a process into a new process group. Process_id is the process to move, process_group is the new process group.
int getpgid(int
process_id);
- Find the process group of a process. Process_id is the process to inspect.
int getpgrp(void);
- Find the process group of the current process. This is identical to
getpgrp(getpid())
. int tcsetpgrp(int
tty, int
foreground_group);
- Change the foreground process group of a tty. Tty is the file descriptor of the tty to change, foreground_group is the new foreground process group.
int tcgetpgrp(int
tty, int *
foreground_group);
- Find the foreground process group of a tty. Tty is the file descriptor of the tty to inspect, foreground_group is returned filled with the foreground process group of the tty.
int kill(int -
process_group, int
signal_number);
- Send a signal to a process group. Note that process_group must be passed as a negative value, otherwise the signal goes to the indicated process.
Differences between POSIX and BSD Process Group Management
The setpgrp()
function is called setpgid()
under POSIX and is essentially identical. You must be careful under POSIX not to use the setpgrp()
function -- usually it exists, but performs the operation of setsid()
.
The getpgrp()
function was renamed getpgid()
, and getpgid()
can only inspect the current process' process group.
The killpgrp()
function doesn't exist at all. Instead, a negative value passed to the kill()
function is taken to mean the process group. Thus you'd perform killpgrp(
process_group)
by calling kill(-
process_group)
.
The ioctl()
commands for querying and changing the foreground process group are replaced with first-class functions:
int tcsetpgrp(int
tty, int
process_group);
int tcgetpgrp(int
tty, int *
process_group);
While the original BSD ioctl()
functions would allow any tty to take on any process group (or even nonexistant process groups) as its foreground tty, POSIX allows only process groups which have the tty as their controlling tty. This limitation disallows some ambiguous (and potentially security-undermining) cases present in BSD.
The TIOCNOTTY ioctl used in BSD is replaced with the setsid()
function, which is essentially identical to:
It releases the current tty and puts the calling process into its own process group. Notice that nothing is done if the calling process is already in its own process group -- this is another new limitation, and eliminates some ambiguous cases that existed in BSD (along with some of BSD's flexibility).
Reference : http://www.cs.ucsb.edu/~almeroth/classes/W99.276/assignment1/signals.html