Thursday, June 11, 2009

POSIX Process Group !

If you want to kill a process by its pid with all its sub process and dont want the child process to continue under init process ? Then process group is the one you may want to look at.

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 -pid

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:

if (getpgrp() != getpid()) { ioctl(tty, TIOCNOTTY, 0); setpgrp(getpid(), getpid()); }

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

1 comment:

callistegadson said...

Upon successful registration, gamers will ready to|be capable of|have the ability to} claim a bonus for the first 4 deposits. Promotions and bonuses are consistent features; subsequently, it's clever to remain updated by subscribing to their newsletter. So, the casino’s thrilling Roulette variations include Auto Roulette, European Roulette, French Roulette, Multiwheel Roulette, and Premier Roulette. 바카라 The on line casino offers a variety of|quite a lot of|a big selection of} reside games like American Live Roulette, Double Ball, French Roulette, and European Live Roulette. Slots.lv offers a reasonably spectacular welcome bonus — a lot as} $7,500 in bonus funds if you use crypto to deposit . The sport selection at Wild Casino is appealing, with loads of desk games.