Sysprog 12

download Sysprog 12

If you can't read please download the document

Transcript of Sysprog 12

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