I have one simple question about signals in Linux systems. As I understand every process has it’s PID and PGID. When I create a process it gets it’s unique PID, now if I would fork a new process with fork() function I would get child process with different PID but the same PGID.
Now, the code
#include<stdio.h>
#include<unistd.h>
int main()
{
int i=3;
int j;
for(j=0;j<i;++j)
{
if (fork() == 0)
{
while(1)
{
}
}
}
printf("created\n");
while(1)
{
}
return 0;
}
when I compile this program and run it with the command
./foo
and wait a sec so he creates his children and I do CTRL-C and then ps aux I can see that the parent and the children are gone, but if I do
./foo
wait for forking to complete and in other terminal do
kill -INT <pid_of_foo>
and ps aux I can see that the parent is gone but children are still alive and eating my CPU.
I am not sure, but it seems that CTRL-C sends the signal to every process that is in some process group and the KILL -SIGNAL pid command sends the signal to the process with PID=pid not PGID=pid.
Am I on the right track? If yes, why the key combination kills processes with PGID and not PID?
Signal delivery, process groups, and sessions
Yes, you are on the right track.
Modern Unix variants since the BSD releases implement sessions and process groups.
You can look at sessions as groups of process groups. The idea was that everything resulting from a single login on a tty or pseudo-tty line is part of a session, and things relating to a single shell pipeline or other logical grouping of processes would be organized into a single process group.
This makes moving “jobs” between the foreground and background and delivering signals more convenient. The shell users mostly doesn’t need to worry about individual processes but can control-C a group of related commands in an intuitive manner.
Signals generated by the keyboard are sent to the foreground process group in a session. The CLI
killcommand you are using delivers signals to individual processes. If you want to try to duplicate the ^C delivery mechanism you can usekill 0; that will send the signal to every member of the same process group, and if executed from a script it may do what you want.Note: I edited your question to change GPID to PGID.