60-256 System Programming: Signals II
Content
COMP-8567 Advanced System Programming:
Signals II
Courtesy of Dr. B. Boufama
modified by Dan Wu
School of Computer Science University of Windsor
–
Instructor: Dr. Dan Wu
Signals II
1
Content
Content
1
Suspending a process
2
Sending a signal to a process
3
Examples
4
Process groups and control terminal Process groups: review
Control terminal
Signals II
2
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Suspending a process
pause()
Synopsis: int pause(void);
The pause() suspends the calling process until it receives a signal.
A call to pause() does not return anything useful. The signal must be one that is not currently set to be ignored by the calling process.
pause() is typically used to wait for a signal.
Signals II
3
man pause (man wait)
See page 6 process 2 slides , also see page 20 in the same slide (page no. are approx.)
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Example: pause() pause.c
#include
#include
#include
#include
void AlarmHandler(int dummy){ static int n = 0;
if(n++ < 6 ){
printf("Beeping Beeping.\n");
alarm(5);
}else
exit(0);
}
int main(int argc, char *argv[]){ alarm(5);
signal(SIGALRM, AlarmHandler);
while(1)
pause();
}
Signals II
4
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Sending a signal to a process
kill()
Synopsis: int kill(pid t pid, int signo);
sends the signal signo to a process or a group of processes, defined by pid.
returns 0 on success, -1 otherwise.
The signal is sent only when at least one of the following conditions is satisfied:
The sending and receiving processes have the same owner.
The sending process is owned by a super-user.
Example
kill(2344, SIGTERM);
To terminate process 2344.
Signals II
5
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
The pid parameter in kill() can take several values with different meanings:
If pid > 1, the signal is sent to the process with id pid. If pid is 0, the signal is sent to all processes in the sender’s process group.
If pid is -1 then
if the sender is owned by a super-user, the signal is sent to all processes, including the sender.
otherwise, the signal is sent to all processes owned by the same owner as the sender.
If pid is equal to -n, with n > 1, the signal is sent to all processes with a process group-id equal to n.
Signals II
6
man kill
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Example: Parent-Child synchronization I (pcs1.c)
#include
#include
#include
#include
void myAlarmHandler(int);
void myAlarmHandler(int dummy){}; // to avoid quitting int main(int argc, char *argv[]){
pid_t pid;
if((pid=fork()) > 0){
printf(“My child should wait until I am done\n”); sleep(4);
printf(“Child, now you can do your job\n”); kill(pid, SIGALRM); // let the child wake up printf(“Parent Exiting\n”);
}
else{
printf(“I have to wait for my parent\n”); signal(SIGALRM, myAlarmHandler); pause();
printf(“OK, now I can do my job\n”); sleep(2);
printf(“Child Exiting\n”);
}
exit(0);
}
Signals II
7
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Example: Parent-Child synchronization I
Output of the previous program
My child should wait until I am done I have to wait for my parent
Child, now you can do your job Parent Exiting
OK, now I can do my job Child Exiting
Signals II
8
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Example: Parent-Child synchronization II (pcs2.c)
#include
#include
#include
#include
void action(int);
void action(int dummy){ sleep(1); printf(“Switching\n”);
}
int main(int argc, char *argv[]){ pid_t pid;
if((pid=fork())>0){//parent sleep(1);
while(1){
printf(“Parent is running\n”); kill(pid, SIGUSR1); signal(SIGUSR1, action); pause();
}
}
else
while(1){//child signal(SIGUSR1, action); pause();
printf(“Child is running\n”); kill(getppid(), SIGUSR1);
}
}
Signals II
9
SIGUSR1
SIGUSR2
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Example: Parent-Child synchronization II
Output of the previous program Parent is running Switching
Child is running Switching
Parent is running Switching
Child is running Switching
Parent is running Switching
Child is running
…
Signals II
10
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Example: a non-blocking wait() (nbwait.c)
#include
#include
#include
#include
#include
void childDeath(int dummy){ pid_t pid;
int status;
pid = wait(&status);
printf(“Child %d has terminated\n”, pid);
}
int main(int argc, char *argv[]){ pid_t pid;
while(1){
signal(SIGCHLD, childDeath); if((pid=fork())==0){
sleep(random()%20); exit(0);
}
printf(“Created a child, pid=%d\n”, pid); sleep(2);
}
}
Signals II
11
SIGCHLD
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Process groups: review Control terminal
Process groups: review
Process groups: review
Unix organizes processes as follows:
Every process is a member of a process group. A child inherits its process group from its parent.
When a process execs, its process group remains the same.
A process may change its process group to a new value using setpgid(). See lecture on Process Control for more details.
(also see “process 3” slide 18-22)
Signals II
12
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Process groups: review Control terminal
Control terminal (ch. 9)
Every process may have an associated control terminal.
A child inherits its control terminal from its parent. A process execs, its control terminal remains the same.
Every terminal is associated with a control process, a piece of software that manages the terminal.
Signals II
13
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Process groups: review Control terminal
The shell and control terminals
When an interactive shell starts, it is the control process of its control terminal:
Executing a foreground process
When a shell executes a foreground process, the child shell changes its group process number to its pid, execs the command and, takes control of the terminal. In this case, signals generated from the terminal go to the command and not to the parent shell.
When the command terminates, the parent shell takes back the control of the terminal.
Executing background process
When a shell executes a background process, the child shell changes its group process number to its pid then execs the command. However, it does not take control of the terminal.
In this case, signals generated from the terminal go to the original parent shell which is still the terminal’s control process.
Signals II
14
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Process groups: review Control terminal
Example 1: CTRL-C goes to all processes in a process group (ctrlc.c)
When CTRL-C is typed, SIGINT is sent to all processes in the
process group of the terminal’s control process.
#include
#include
#include
#include
void CTRL_handler(int);
void CTRL_handler(int dummy){
printf(“Process %d got a CTRL-C, exit\n”, getpid()); exit(2);
}
int main(int argc, char *argv[]){ int i;
printf(“First process, PID=%d, PPID=%d, PGID=%d\n”, getpid(), getppid(), getpgid(0));
signal(SIGINT, CTRL_handler);
for(i=1; i<=3; i++) fork();
printf("PID=%d PGID=%d\n", getpid(), getpgid(0)); pause();
}
Signals II
15
15
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Process groups: review Control terminal
Output of example running foreground
CTRL-C is pressed after all the processes are created:
First process, PID=3928, PPID=3885, PGID=3928 PID=3928 PGID=3928
PID=3931 PGID=3928 PID=3929 PGID=3928 PID=3930 PGID=3928 PID=3932 PGID=3928 PID=3933 PGID=3928 PID=3934 PGID=3928 PID=3935 PGID=3928
ˆCProcess 3932 got a CTRL-C, exit Process 3930 got a CTRL-C, exit Process 3929 got a CTRL-C, exit Process 3935 got a CTRL-C, exit Process 3931 got a CTRL-C, exit Process 3928 got a CTRL-C, exit Process 3934 got a CTRL-C, exit Process 3933 got a CTRL-C, exit
Signals II
16
Suspending a process Sending a signal to a process
Examples Process groups and control terminal
Process groups: review Control terminal
Example 2: CTRL-C (ctrlc2.c)
void CTRL_handler(int dummy){
printf("Process%d got CTR-C, exiting\n", getpid()); exit(0);
}
int main(int argc, char *argv[]){ int i, pid;
signal(2, CTRL_handler); if((pid=fork()) == 0){
setpgid(0, getpid());//child is in its own group printf("PID=%d, PGID=%d\n",getpid(),getpgid(0));
}else
printf("PID=%d, PGID=%d\n", getpid(), getpgid(0));
for(i=1; i<=10; i++){
printf("Process %d is still alive\n", getpid()); sleep(2);
}
}
What happens when we press CTRL-C?
Signals II
17