/
1 CS  3733  Operating Systems 1 CS  3733  Operating Systems

1 CS 3733 Operating Systems - PowerPoint Presentation

mitsue-stanley
mitsue-stanley . @mitsue-stanley
Follow
348 views
Uploaded On 2018-09-21

1 CS 3733 Operating Systems - PPT Presentation

Instructor Dr Turgay Korkmaz Department Computer Science The University of Texas at San Antonio Office NPB 3330 Phone 210 4587346 Fax 210 4584437 email korkmazcsutsaedu ID: 673713

signals signal set amp signal signals amp set int handler process sigset sig sigsuspend sigaction mask block wait pause

Share:

Link:

Embed:

Download Presentation from below link

Download Presentation The PPT/PDF document "1 CS 3733 Operating Systems" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.


Presentation Transcript

Slide1

1

CS 3733 Operating Systems

Instructor: Dr. Turgay KorkmazDepartment Computer ScienceThe University of Texas at San AntonioOffice: NPB 3.330Phone: (210) 458-7346 Fax: (210) 458-4437 e-mail: korkmaz@cs.utsa.eduweb: www.cs.utsa.edu/~korkmaz

Topics: Signals(USP Chapter 8.1-8.6)

These slides are prepared based on the materials provided by Drs. Robbins, Zhu, and Liu. Thanks to all.Slide2

2Outline

Overview of signalsConcepts and general terminologyPOSIX required signals

Signal generations: kill vs. raiseBlock signals and process signal masksSignal handles: catch vs. ignore SignalsWait signals: pause, sigsuspend and sigwaitErrors and async-signal safetyDepartment of Computer Science @ UTSASlide3

MotivationHow would you stop this program?Did you ever pres Ctrl-C when running a program?Did you ever use > kill -9 PIDIf yes, can you explain what is happening?We send a SIGNAL to a process…A signal is a software notification of an event to a process.Accordingly, the process takes an action (e.g., quit).Is this a SYNCHRONOUS or an ASYNCHRONOUS event?3

while(n=5){

printf(“n is %d\n”, n--); ...}

// vs. n==5Slide4

Signal Concept and TerminologyA signal is generated when the event that causes the signal occurs.A signal is delivered when the process takes action based on the signal.The lifetime of a signal is the interval between its generation and delivery.A signal that has been generated but not yet delivered is pending.A process catches a signal if it executes a signal handler when the signal is delivered.Alternatively, a process can ignore a signal when it is delivered, that is to take no action.4

Signal handler - functionSlide5

Signal Concept and Terminology - ExerciseA signal is __________when the event that causes the signal occurs.A signal is _________ when the process takes action based on the signal.The ________of a signal is the interval between its generation and delivery.A signal that has been generated but not yet delivered is_________.A process ________ a signal if it executes a signal handler when the signal is delivered.Alternatively, a process can ______ a signal when it is delivered, that is to take no action.5

Signal handler - function

generated

delivered

lifetime

pending

catches

ignore

Slide6

Signal Concept and Terminology (cont’d)The function sigaction is used to specify what is to happen to a signal when it is delivered.Each signal has a default action which is usually to terminate the process.The function sigprocmask is used to modify the signal mask.The signal mask determines the action to be taken when the signal is generated. It contains a list of signals to be

blocked.A blocked signal is not delivered to a process until it is unblocked.

6SignalMaskAction1

23

4Slide7

POSIX Required Signals: Table 8.17

REFSlide8

Generate Signals: Command LineThe kill commandSend a signal to a process from consoleThe usage of kill kill –l : list the signals the system understandskill [–signal] pid: send a signal to a process (pid)The default is SIGTERMExample: to unconditionally kill a process kill -9 pidkill –KILL pid

8Slide9

Generate Signals: Running ProgramThe kill system call#include <sys/types.h>#include <signal.h> int kill(pid_t pid, int sig);Example: send SIGUSR1 to process 3423if (kill(3423, SIGUSR1) == -1) perror

("Failed to send SIGUSR1 signal");Normally, do NOT specify pid as a numberUse

getpid() or getppid()9Slide10

Generate Signals: Running Program (cont.)Example: a child process kills its parentif (kill(getppid(), SIGTERM) == -1) perror ("Failed to kill parent");The raise system call: send a signal to itselfif (raise(SIGUSR1) != 0) perror("Failed to raise SIGUSR1");What do you think the following program does?int main(void) { alarm(10);

for ( ; ; ) ; }

10After 10 seconds, it gets SIGALRM, which (by default) kills the process…Slide11

Signal Mask and Signal SetsHow do you deal with a set of signals?How can we prevent a signal from being delivered?11SignalMask

Action1

234Slide12

Signal Mask and Signal SetsEach process has a signal maskDefines the set of signals to be BLOCKED!The set of signals: type sigset_t (originally was int, one bit per signal) Routines to handle signal sets (compare to select(…) which handles FDs)#include <signal.h> int sigemptyset( sigset_t *set);

int sigfillset( sigset_t *set);

int sigaddset( sigset_t *set, int signo); int sigdelset( sigset_t *set, int signo); int

sigismember(const sigset_t *set, int signo

);

12

initializes the set to contain no signals

puts all signals in the set

adds one signal to the set

removes one signal from the set

tests to see if a signal is in the set

if((

sigemptyset

(&

twosigs

) == -1) ||

(

sigaddset

(&

twosigs

, SIGINT) == -1) ||

(

sigaddset

(&

twosigs

, SIGQUIT) == -1))

perror

("Failed to set up signal mask");Slide13

Sys. Call to Modify Signal Mask: sigprocmask The system call: sigprocmask int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);how:

an integer specifying how the signal mask is to be modified: SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASKset: a pointer to a signal set to be used in the modification. If set is NULL, no modification is made.

oset: If oset is not NULL, the sigprocmask returns in *oset the signal set before the modification.Example: initialize a signal set and set masksigset_t newsigset; if ((sigemptyset(&newsigset) == -1) || (sigaddset(&newsigset

, SIGINT) == -1)) perror("Failed to initialize signal set"); else if (sigprocmask(

SIG_BLOCK

, &

newsigset,NULL

) == -1)

perror

("Failed to block SIGINT”);

13

Some signals

(

e.g., SIGSTOP and SIGKILL

)

cannot be blocked. Slide14

Example: Block/Unblock SIGINT14Alternating block/unblock SIGINT

Ctrl+C

: will not return immediately if in block section!

Ctrl+C: will return immediately if in unblock section!Slide15

Example: block all signals while creating two pipes, then restore old ones15int makepair(char *pipe1, char *pipe2) { sigset_t blockmask;

sigset_t oldmask;

int returncode = 0; if(sigfillset(&blockmask) == -1) return -1; if(sigprocmask(SIG_SETMASK, &blockmask, &oldmask) == -1)return -1;

if(((mkfifo(pipe1, RW_MODE) == -1) && (errno != EEXIST)) || ((mkfifo

(pipe2, RW_MODE) == -1) && (

errno

!= EEXIST))) {

returncode

=

errno

;

unlink(pipe1); unlink(pipe2);

}

if((

sigprocmask

(SIG_SETMASK, &

oldmask

, NULL)

== -1) && !

returncode

)

returncode

=

errno

;

if(

returncode

) {

errno

=

returncode

;

return -1;

}

return 0;

}

#include <

errno.h

>

#include <

signal.h

>

#include <

unistd.h

>

#include <sys/

stat.h

>

#define R_MODE (S_IRUSR | S_IRGRP | S_IROTH)

#define W_MODE (S_IWUSR | S_IWGRP | S_IWOTH)

#define RW_MODE (R_MODE | W_MODE)Slide16

Example: Block Signals & fork: child inherit mask16No interruption during child’s execution!

mask contains ALL signals!Slide17

Catching and Ignoring Signals: sigactionLet caller to examine or specify the action associated with a specific signal.17SignalMask

Action1

234Slide18

Set up signal handler: sigaction int sigaction(int signo, struct sigaction *act, struct sigaction *oact);

signo: specifies the signal number for the action. act: a pointer to a struct

sigaction structure that specifies the action to be taken. oact: a pointer to a struct sigaction structure that receives the previous action associated with the signal. If act is NULL, do not change the action associated with the signal. Either act or oact may be NULL.18Slide19

struct sigaction structurestruct sigaction { void (*sa_handler)(int); /* SIG_DFL, SIG_IGN or pointer to function (no return value) */

sigset_t sa_mask

; /* additional signals to be blocked */ int sa_flags; /* special flags and options */ void (*sa_sigaction) (int

, siginfo_t *, void *); /*

realtime

handler */

};

SIG_DFL: restore the default action for the signal.

SIG_IGN: handle the signal by ignoring it

(throwing it away).

Pointer to a user defined function (signal handler)

The storage for

sa_handler

and

sa_sigaction

may overlap, and an application should use only one of these members to specify the action.

If the

SA_SIGINFO

flag of the

sa_flags

field is

cleared

,

sa_handler

specifies the action to be taken.

If the

SA_SIGINFO

flag of the

sa_flags

field is

set

,

sa_sigaction

field specifies a signal-catching function.

19Slide20

Example: new handler for SIGINTSet up a signal handler that catches the SIGINT signal generated by Ctrl-C.20act.sa_handler=SIG_DFL;act.sa_handler=SIG_IGN;// and use the same procedure

How about ignoring SIGINT if the default action is in effect for this signal? (next slide)

How can we reset SIGINT to the default handler or ignore it?Slide21

Example: ignore SIGINT if the default action is in effect for this signal. struct sigaction act;if(sigaction(SIGINT,NULL, &act)==-1)/* Find current SIGINT handler */ perror("Failed to get old handler for SIGINT");else if(act.sa_handler == SIG_DFL){

/* if SIGINT handler is default */ act.sa_handler = SIG_IGN;

/* set new SIGINT handler to ignore */ if(sigaction(SIGINT, &act, NULL) == -1) perror("Failed to ignore SIGINT");}21Slide22

Exercise: A program that terminates gracefully on ctrl-C Ex1: Terminate program after receiving ctrl-C three timesEx1: Write a program that terminates gracefully on ctrl-C! (i.e., finish doSomething() then quit!)while(1) { // doSomething() }Print a msg that Program ends gracefully…22Slide23

Ex1: and Ex2: need modifications here… 23Slide24

Wait for SignalsSignals provide a method for waitingfor an event without busy waiting.int pause(void); int sigsuspend(const sigset_t *sigmask);int sigwait(

sigset_t *restrict sigmask,

int *restrict signo);24Si

gnalMaskAction

1

2

3

4Slide25

Wait for Signal: pause()The usage of pause() #include <unistd.h> int pause(void);Blocks/suspends the process until it receives a signal!Always return -1; if interrupted, set errno as EINTRHowever, no information about which signal causes it return!Can we use pause() to wait for a particular signal?How to know which signal?The signal handler of the wanted signal sets a flagAfter return from pause(), check the flag25

…pause();….Slide26

Wait for Signal: pause() – cont.static volatile sig_atomic_t sigreceived = 0; void catch_signal(int signo){     sigreceived = 1; //handler}…

while(sigreceived == 0) pause();

26What if the desired signal occurs between condition check and pause()? -- Wait for another occurrence again or other signals! -- What if there is no other signal! – Deadlock So, we need to block the signal when checking the condition!

struct

sigaction

act;

act.sa_handler

=

catch_signal

;

act.sa_flags

= 0;

sigemptyset

(&

act.sa_mask

);

sigaction

(SIGUSR1, &act, NULL);Slide27

Wait for Signal: pause() – cont.What about this solution?static volatile sig_atomic_t sigreceived = 0; int signum = SIGUSR1; //desired signal sigset_t sigset;sigemptyset(&

sigset); sigaddset(&

sigset, signum); //desired signal sigprocmask(SIG_BLOCK, &sigset, NULL); while(sigreceived == 0) pause(); 27

It executes pause while the signal is blocked, so theprogram never receives the signal and pause never returns!We need to atomically unblock the signal and suspend

the process

after checking the condition!Slide28

The sigsuspend() FunctionSuspends the process until a signal is receivedWe will use it to unblock the signal and pause the process in an atomic manner#include <signal.h> int sigsuspend(const sigset_t *

sigmask);Sets the signal mask to the one pointed to by sigmask and suspends the process until a signal is caught (in

atomic manner).It returns when the signal handler of the caught signal returns. This function always returns -1. Also the signal mask is restored to what it was before this function was called. 28Slide29

A wrong way to wait for a signal: wait for SIGUSR1sigfillset(&sigmost);sigdelset(&sigmost, SIGUSR1);while(sigreceived == 0) sigsuspend(&sigmost);The sigmost signal set contains all signals except the one to wait for. When the process suspends, only the signal SIGUSR1 is unblocked and so it seems that only this signal can cause sigsuspend

to return. But, it has the same problem as pause. If the signal is delivered before the sigsuspend call, the process still suspends itself and deadlocks if another SIGUSR1 signal is not generated.

29Slide30

How to use sigsuspend() to wait for a signalHave an handler to set a flag for the signal (e.g. signo)Block the signal with signoCreate a sigmask without signowhile(flag == 0) sigsuspend(sigmask);Signal signo

is blocked until sigsuspend is calledSigsuspend unblocks the signal signo and suspends When the signal is caught, the handler will be executed. Then sigsuspend returns and restores the previous mask (i.e., block the signal with

signo again) 30Slide31

A correct way to wait for a signal: wait for SIGUSR1sigset_t blockmask, sigmask; sigemptyset(&blockmask); sigemptyset(&sigmask); sigaddset(&blockmask, SIGUSR1); sigprocmask

(SIG_BLOCK, &blockmask, NULL); while(sigreceived

== 0) sigsuspend(&sigmask);31static volatile sig_atomic_t

sigreceived = 0;

void

catch_signal

(

int

signo

){

   

sigreceived

= 1;

}

Sets the signal mask to the one in

sigmask

(i.e.,

unblocks SIGUSR1 and suspends the process until a signal happens)

.

When it returns, the signal mask is restored to what it was before it was called.

Do tk-quiz-16Slide32

A correct way to wait for a signal while allowing other signals to be handled: 3. sigset_t maskblocked, maskold, maskunblocked;4. int signum = SIGUSR1;5.6. sigprocmask(SIG_SETMASK, NULL, &maskblocked

);7. sigprocmask(SIG_SETMASK, NULL, &maskunblocked

);8. sigaddset(&maskblocked, signum);9. sigdelset(&maskunblocked, signum);10. sigprocmask(SIG_BLOCK, &maskblocked, &

maskold);11. while(sigreceived == 0) 12. sigsuspend(&maskunblocked

);

13.

sigprocmask

(SIG_SETMASK, &

maskold

, NULL);

32

OPT

Robust

version Slide33

The sigwait() Function:An alternative way to wait for signalsint sigwait(const sigset_t *restrict sigmask, int *restrict signo); Block all signals that we want to wait forPut the signals you want to wait for in a sigset_tcall sigwait, which blocks the process until at least one of these signals is pending.

It removes one of the pending signals and gives you the corresponding signal number in the second parameter.Do what you want: no signal handler needed.It returns 0 on success and -1 on error with errno set

33How is this different than sigsuspend?Slide34

Differences between sigwait() and sigsuspend()Both functions have a first parameter that is a pointer to a signal set (sigset_t *). For sigsuspend, this set holds the new signal mask and so the signals that are not in the set are the ones that can cause sigsuspend to return. For sigwait, this parameter holds the set of signals to be waited for, so the signals in the set are the ones that can cause the sigwait to return. Unlike sigsuspend, sigwait does not change the process signal mask. The signals in sigmask should be blocked before sigwait is called.

34Slide35

Count Signals35

First, block the signal

Wait only for the signal!Slide36

Issues in Handling Signals…Errors and async-signal safetyThree issues in handling signals:Certain blocking system calls (e.g., read) return -1 and set errno to EINTR if a signal is caught while the function is blocked.Error handling in signal handlersAsync-signal safety36Slide37

Signals and blocking system calls Certain blocking system calls will return -1 with errno set to EINTR if a signal is caught while the function is blocked.Check the man page to see if a system call can set errno to EINTR.If this happens, you should usually restart the function since a real error has not occurred. The restart library handles this for many of the most important system calls. Look at the functions in the restart library. 37Slide38

Handling errors in signal handlersIf you use a function that can modify errno in a signal handler, you must make sure that it does not interfere with error handling in the main part of the program.There is only one errno and it is used by both the main program and by the signal handler.Solution: in the signal handler, save and restore errno. void myhandler(int signo) { int

esaved; esaved

= errno; write(STDOUT_FILENO, "Got a signal\n", 13); errno = esaved; } 38Slide39

Async-signal safety.Only certain system calls and library functions may be used safely in a signal handler.The strtok function is an example of a function that might have a problem.In fact, the POSIX standard only guarantees that a small number of functions are async-signal safe, that is safe to use in a signal handler and the main program.Other functions may be async-signal safe in some implementations.Almost none of the functions in the standard C library are on the list.39Slide40

Functions that POSIX guarantees to be async-signal safe.40_Exit execve lseek sendto

stat

_exit fchown lstat setgid symlink accept fcntl mkdir setpgid

sysconf access fdatasync

mkfifo

setsid

tcdrain

aio_error

fork

open

setsockopt

tcflow

aio_return

fpathconf

pathconf

setuid

tcflush

aio_suspend

fstat

pause

shutdown

tcgetattr

alarm

fsync

pipe

sigaction

tcgetpgrp

bind

ftruncate

poll

sigaddset

tcsendbreak

cfgetispeed

getegid

posix_trace_event

sigdelset

tcsetattr

cfgetospeed

geteuid

pselect

sigemptyset

tcsetpgrp

cfsetispeed

getgid

raise

sigfillset

time

cfsetospeed

getgroups

read

sigismember

timer_getoverrun

chdir

getpeername

readlink

signal

timer_gettime

chmod

getpgrp

recv

sigpause

timer_settime

chown

getpid

recvfrom

sigpending

times

clock_gettime

getppid

recvmsg

sigprocmask

umask

close

getsockname

rename

sigqueue

uname

connect

getsockopt

rmdir

sigset

unlink

creat

getuid

select

sigsuspend

utime

dup

kill

sem_post

sleep

wait

dup2

link

send

socket

waitpid

execle

listen

sendmsg

socketpair

write Slide41

Signals and Threads How do you handle signals in a threaded environment? 41Slide42

Handling signals in a multithreaded environmentIf a signal is sent to a threaded program, any of the threads can handle the signal. Each thread inherits the process signal mask, but each thread has its own signal mask that can be modified with pthread_sigmask. sigprocmask should not be used in a threaded environment, but it can be used before the threads are created. The simplest way to handle signals in a multithreaded environment is to have a thread dedicated to signal handling.42Slide43

Handling signals in a multithreaded environment - contIssues involving signal safety can be handled by using sigwait: The main process blocks all signals before creating any threads. No signal handlers are set up. A thread is created to handle the signals. That thread sets up a sigset_t containing the signals of interest. It loops, calling sigwait and handles the pending signals.43Slide44

EXTRAS….44Slide45

Real Time Signals (USP 9.4)sigactionvoid(*sa_sigaction) (int, siginfo_t *, void *); /* realtime handler */When SA_SIGINFO flag is setsa_sigaction specifies the action to be takenA new type of signal handler: take 3 parametersSignals for this type of signal handlers are queuedUse sigqueue instead of kill to send one of these signalsint sigqueue(pid_t

pid, int

signo, const union sigval value);45Slide46

Set Up a Real Time Signal Handler46Slide47

An Example: Send a queue signal47