System System ProgrammingProgramming
Project 2Project 2
Due : 4/19 ...?Due : 4/19 ...?
Foreground & BackgroundForeground & Background Foreground jobForeground job
Only one at momentOnly one at moment Having user’s focusHaving user’s focus
Background jobBackground job Many jobs runningMany jobs running
in backgroundin background They are totallyThey are totally
inpendentinpendent No focusNo focus
FGFG
BGBGBGBG
BGBG
FG & BG & Stopped in UnixFG & BG & Stopped in Unix
BG FG
Stopped
Ctrl+Zfgbg
fgcmd& cmd
FG & BG & Stopped FG & BG & Stopped ExampleExample>parrot hi>parrot hi01-hi01-hi02-hi02-hi>jobs>jobs[1] Stopped parrot hi[1] Stopped parrot hi>bg 1>bg 1>>03-hi03-hi04-hi04-hi>ls>lshello.c abc.txt shellhello.c abc.txt shell>>05-hi05-hi06-hi06-hi
Ctrl+ZCtrl+Z
>parrot hi &>parrot hi &>>01-hi01-hi02-hi02-hi>jobs>jobs[1] Running parrot hi &[1] Running parrot hi &>>03-hi03-hi04-hi04-hi>fg 1>fg 105-hi05-hi......10-hi10-hi>>
Ex.1 Ex.1 Ex.2 Ex.2
Signal Handling in shellSignal Handling in shell
Ex. Terminating FG jobEx. Terminating FG job
user push Ctrl+Cuser push Ctrl+C
Shell receives ‘SIGINT’ signalShell receives ‘SIGINT’ signal
Shell sends ‘SIGINT’ to FG jobShell sends ‘SIGINT’ to FG job
FG job receives ‘SIGINT’FG job receives ‘SIGINT’and terminatesand terminates
Important Unix SignalsImportant Unix Signals SIGINT (Ctrl+C by user)SIGINT (Ctrl+C by user)
terminate processterminate process SIGTSTP (Ctrl+Z by user)SIGTSTP (Ctrl+Z by user)
stop processstop process SIGCONT (from shell to child)SIGCONT (from shell to child)
continue stopped processcontinue stopped process SIGCHLD (from child to shell)SIGCHLD (from child to shell)
notify state change of child processnotify state change of child process Run -> CompleteRun -> Complete Run -> Terminate or StopRun -> Terminate or Stop Stop -> RunStop -> Run
> kill –l : show all signals> kill –l : show all signals
signal(), sigaction()signal(), sigaction()#include <signal.h>#include <signal.h>int flag;int flag;void myHandler (int sig) {void myHandler (int sig) {
flag=1; // this can stop while loopflag=1; // this can stop while loop}}main() {main() {
flag=0; while (!flag); printf(“1”);flag=0; while (!flag); printf(“1”);flag=0; while (!flag); printf(“2”);flag=0; while (!flag); printf(“2”);flag=0; while (!flag); printf(“3”);flag=0; while (!flag); printf(“3”);
}}
// After myHandler is executed// After myHandler is executed// SIGINT handler changes to default// SIGINT handler changes to defaultsignal(SIGINT, myHandler);signal(SIGINT, myHandler);
// SIGINT handler is myHandler forever// SIGINT handler is myHandler foreverstruct sigaction action, old_action;struct sigaction action, old_action;action.sa_handler = myHandler;action.sa_handler = myHandler;sigemptyset(&action.sa_mask);sigemptyset(&action.sa_mask);action.sa_flags = SA_RESTART;action.sa_flags = SA_RESTART;sigaction(SIGINT, &action, &old_action;sigaction(SIGINT, &action, &old_action;
This is exampleThis is exampleof busy-waitingof busy-waiting
Specification 1/2Specification 1/2 Ctrl+CCtrl+C terminates FG job terminates FG job
Ctrl+C shouldn’t terminate shellCtrl+C shouldn’t terminate shell Do nothing if there is no FG jobDo nothing if there is no FG job
Ctrl+ZCtrl+Z stops FG job stops FG job Ctrl+Z shouldn’t stop shellCtrl+Z shouldn’t stop shell Do nothing if there is no FG jobDo nothing if there is no FG job
Running in backgroundRunning in background Putting ‘&’ in the end of commandPutting ‘&’ in the end of command
Terminate all jobs when shell ‘Terminate all jobs when shell ‘exitexit’’
Specification 2/2Specification 2/2 ‘‘jobs’jobs’ command command
Shows list of job stateShows list of job state [job_id] state command[job_id] state command State is ‘BG running’ or ‘Stopped’State is ‘BG running’ or ‘Stopped’
‘‘fg job_id’fg job_id’ command command Change ‘job_id’ job to FG jobChange ‘job_id’ job to FG job Stopped or BG Stopped or BG FG FG
‘‘bg job_id’bg job_id’ command change a job to BG command change a job to BG Change ‘job_id’ job to BG jobChange ‘job_id’ job to BG job Stopped Stopped BG BG
- Don’t use exec().- Don’t use exec().- If ‘job_id’ is not specified, it’s up to you.- If ‘job_id’ is not specified, it’s up to you.
Make it work like bashMake it work like bash
SIGINT, SIGTSTP HandlerSIGINT, SIGTSTP Handlersigint_handler {sigint_handler {
search FG jobsearch FG jobif there is FG jobif there is FG job
send SIGINT to FG job to terminatesend SIGINT to FG job to terminate}}
sigtstp_handler {sigtstp_handler {search FG jobsearch FG jobif there is FG jobif there is FG job
change the job’s state to Stoppedchange the job’s state to Stoppedsend SIGTSTP to FG job to stopsend SIGTSTP to FG job to stop
}}Use ‘kill (pid, sig)’ to send signal!!Use ‘kill (pid, sig)’ to send signal!!
SIGCHLD HandlerSIGCHLD Handlersigchld_handler {sigchld_handler {
get pid whose state changed toget pid whose state changed to completed / terminated / stopped / continue ... completed / terminated / stopped / continue ...if it is terminated(SIGINT) or completedif it is terminated(SIGINT) or completed
delete the job from job listdelete the job from job listshell comes backshell comes back
else if it is stopped(SIGTSTP)else if it is stopped(SIGTSTP)shell comes backshell comes back
}}
See Hints page!!See Hints page!!
HintsHints waitpid(pid, &status, option)waitpid(pid, &status, option)
If pid=-1, wait for any child to change stateIf pid=-1, wait for any child to change state If option = WUNTRACED|WNOHANGIf option = WUNTRACED|WNOHANG
Return value is pid of process when process is terminReturn value is pid of process when process is terminated or stopped. 0 or -1 for other state changeated or stopped. 0 or -1 for other state change
WNOHANG means doesn’t waitWNOHANG means doesn’t wait Status can be checked with macros.Status can be checked with macros.
- If WIFEXITED(status) > 0, completed - If WIFEXITED(status) > 0, completed - If WIFSIGNALED(status) > 0, terminated - If WIFSIGNALED(status) > 0, terminated - If WIFSTOPPED(status) > 0, stopped - If WIFSTOPPED(status) > 0, stopped
from from http://database.sarang.net/study/glibc/24.htmhttp://database.sarang.net/study/glibc/24.htm and my try and error...T.Tand my try and error...T.T
HintsHints Signal from group A goes to all process in grouSignal from group A goes to all process in grou
p Ap A Shell’s group and child group is same as defaulShell’s group and child group is same as defaul
t.t. But only shell should receive user’s signal.But only shell should receive user’s signal.
setpgid(pid, pgid)setpgid(pid, pgid) Set process group idSet process group id
If pid=0, it is same as getpid()If pid=0, it is same as getpid() If pgid=0, it is same as pid.If pgid=0, it is same as pid.
(pid becomes a group leader)(pid becomes a group leader) getpgrp(), getpgid(pid)getpgrp(), getpgid(pid)
get process group idget process group id
HintsHints sigprocmask(mode, set, oldset)sigprocmask(mode, set, oldset)
Block signalsBlock signals Example codeExample code sigset_t sigset, oldset;sigset_t sigset, oldset;
sigemptyset(&sigset);sigemptyset(&sigset);sigaddset(&sigset, SIGCHLD); sigaddset(&sigset, SIGCHLD); sigprocmask(SIG_BLOCK, &sigset, &oldset);sigprocmask(SIG_BLOCK, &sigset, &oldset);
/* run the job *//* run the job *//* add job to job list *//* add job to job list */sigprocmask(SIG_UNBLOCK, &sigset, &oldset);sigprocmask(SIG_UNBLOCK, &sigset, &oldset);
Short jobs are terminated(sending SIGCHLD) before shell adds tShort jobs are terminated(sending SIGCHLD) before shell adds them to job list. Mask prevents this by blocking SIGCHLD.hem to job list. Mask prevents this by blocking SIGCHLD.