Sysprog 12
-
Upload
ahmed-mekkawy -
Category
Technology
-
view
791 -
download
1
Transcript of Sysprog 12
C/C++ Linux System Programming
Session 12User-space System Programming
– session 2
Outline
● Signals● Job Control● Scheduling● IPC Intro
Sending Signals
● int kill(pid_t pid, int sig);● int raise(int sig); // = kill(getpid(), sig);● int sigqueue(pid_t pid, int sig, const union sigval
value); // value is a payload (IPC w/data!!)
Handling Signals – old school
● Handler
– typedef void (*sighandler_t)(int);
– sighandler_t signal(int signum, sighandler_t handler);
– SIG_IGN / SIG_DFL
– Example from sshd.c:
static voidmain_sigchld_handler(int sig){
int save_errno = errno;pid_t pid;int status;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || (pid < 0 && errno == EINTR))
;
signal(SIGCHLD, main_sigchld_handler);errno = save_errno;
}
Signal sets
– int sigemptyset(sigset_t *set); // Init
– int sigfillset(sigset_t *set); // Init with all
– int sigaddset(sigset_t *set, int signum);
– int sigdelset(sigset_t *set, int signum);
– int sigismember(const sigset_t *set, int signum);
– Non-POSIX:● int sigisemptyset (sigset_t *set);● int sigorset (sigset_t *dest, sigset_t *left, sigset_t *right);● int sigandset (sigset_t *dest, sigset_t *left, sigset_t *right);
Masking
● Mask/Unmask– int sigprocmask(int how, const sigset_t *set, sigset_t
*oldset);
– how: SIG_BLOCK/SIG_UNBLOCK/SIG_SETMASK
● Check pending (temporarily masked)– int sigpending(sigset_t *set);
● Waiting for a signal– int pause(void);
– int sigsuspend(const sigset_t *mask);
Masking Example -ssh/server_loop.c
/* block SIGCHLD while we check for dead children */ sigemptyset(&nset); sigaddset(&nset, SIGCHLD); sigprocmask(SIG_BLOCK, &nset, &oset); if (child_terminated) { debug("Received SIGCHLD."); while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || (pid < 0 && errno == EINTR)) if (pid > 0) session_close_by_pid(pid, status); child_terminated = 0; } sigprocmask(SIG_SETMASK, &oset, NULL);}
Versatile Signal Handling Interface
● int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
● Important sigaction fields:– void (*sa_handler)(int);
– void (*sa_sigaction)(int, siginfo_t *, void *);
– sigset_t sa_mask;
● Important siginfo_t:– si_signo , si_uid, si_value, si_addr
Example - inetd memset(&sa, 0, sizeof(sa)); sigaddset(&sa.sa_mask, SIGALRM); sigaddset(&sa.sa_mask, SIGCHLD); sigaddset(&sa.sa_mask, SIGHUP); sa.sa_handler = retry_network_setup; sigaction_set(SIGALRM, &sa); sa.sa_handler = reread_config_file; sigaction_set(SIGHUP, &sa); sa.sa_handler = reap_child; sigaction_set(SIGCHLD, &sa); sa.sa_handler = clean_up_and_exit; sigaction_set(SIGTERM, &sa); sa.sa_handler = clean_up_and_exit; sigaction_set(SIGINT, &sa); sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, &saved_pipe_handler);
static void clean_up_and_exit(int sig UNUSED_PARAM){,,,,
remove_pidfile(_PATH_INETDPID); exit(EXIT_SUCCESS);}
int FAST_FUNC sigaction_set(int signum, const struct sigaction *act){ return sigaction(signum, act, NULL);}
Some Signal Notes
● Behavior in fork● Behavior in exec● Process Group relevance● System call interruptions● Intro to race conditions
– Critical region
– Reentrancy
– Minimal work
– Sigatomic_t
system/popen
● fork/exec (/bin/sh)● Security hole● Signal blocking
Scheduling
● Time-sharing (timeslices)● States● Process table● Context switch● Priorities● Preemptive vs Cooperative Multitasking● Idle process
2.4 Scheduling● Nice values
– [-20,19], -20 is not nice, i.e. high priority
– Time slice length & run queue order
– Superuser to decrement
● int nice(int inc); // nice(0) is current● get/set priority
– int getpriority (int which, int who);
– int setpriority (int which, int who, int prio);
– Absolute
– PRIO_RPOCESS, PRIO_PGRP, PRIO_USER
Relinquishing CPU
– int sched_yield ● why?● 2.4 vs 2.6 (RT vs non-RT)
– Sleep● unsigned int sleep(unsigned int seconds);● int nanosleep(const struct timespec *rqtp, struct timespec
*rmtp);● int usleep(useconds_t usec);
Real-time Scheduling● Real-time - soft/hard
– determinism
● Priorities: 1-99, 0 non-RT
● Scheduling classes– Round-robin
– FIFO
● Chrt● Be “nice” !!!
struct sched_param { /* ... */ int sched_priority; /* ... */};
int sched_getparam (pid_t pid, struct sched_param *sp);
int sched_setparam (pid_t pid, const struct sched_param *sp);
Processor Affinity
● SMP● Affinity: Which
processor?– By default, try the
same and hereditary
● Do I care? -- Cache coherency
● Do I really care?– http://www.linuxjournal.
com/article/6799
pid = atol(argv[1]); sscanf(argv[2], "%08lx", &new_mask); if (sched_getaffinity(pid, len, &cur_mask) < 0) { perror("sched_getaffinity"); return -1; } printf("pid %d's old affinity: %08lx\n", pid, cur_mask); if (sched_setaffinity(pid, len, &new_mask)) { perror("sched_setaffinity"); return -1; } if (sched_getaffinity(pid, len, &cur_mask) < 0) { perror("sched_getaffinity"); return -1; }
Time
● Monotonic time / real time / process time● POSIX
– int clock_getres(clockid_t clk_id, struct timespec *res);
– int clock_gettime(clockid_t clk_id, struct timespec *tp);
– int clock_settime(clockid_t clk_id, const struct timespec *tp);
System time● get/set
– int gettimeofday(struct timeval *tv, struct timezone *tz);
– int settimeofday(const struct timeval *tv, const struct timezone *tz);
– time_t time(time_t *t); // seconds
● Printable – char *ctime(const time_t *timep); //And family
● int adjtime(const struct timeval *delta, struct timeval *olddelta);
Examples from NTP
gettimeofday(&tv, 0);epoch = tv.tv_sec;
...fprintf(stdout, "# %s\n# %s", filename, ctime(&epoch));
curtime = time(0);printf("Starting: %s", ctime(&curtime));
Interval Timers● Set a timer● Signal when expired
int getitimer(int which, struct itimerval *value);int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);struct itimerval { struct timeval it_interval; /* next value */ struct timeval it_value; /* current value */};struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */};unsigned int alarm(unsigned int seconds);
Example – ping.c
static void noresp(int ign UNUSED_PARAM){
printf("No response from %s\n", hostname);
exit(EXIT_FAILURE);}
main(){
...signal(SIGALRM, noresp);alarm(5); /* give the host 5000ms to respond */
...}
IPC Intro
● Share data● Synchronize● Mutual Exclusion
– Critical region
– Semaphores