Post on 16-Apr-2017
C/C++ Linux System Programming
Session 12
User-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
Click to edit the title text
Click to edit the outline text format
Second Outline Level
Third Outline Level
Fourth Outline Level
Fifth Outline Level
Sixth Outline Level
Seventh Outline Level
Eighth Outline Level
Ninth Outline Level