sysprog 12
TRANSCRIPT
![Page 1: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/1.jpg)
C/C++ Linux System Programming
Session 12User-space System Programming
– session 2
![Page 2: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/2.jpg)
Outline
● Signals● Job Control● Scheduling● IPC Intro
![Page 3: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/3.jpg)
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!!)
![Page 4: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/4.jpg)
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;
}
![Page 5: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/5.jpg)
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);
![Page 6: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/6.jpg)
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);
![Page 7: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/7.jpg)
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);}
![Page 8: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/8.jpg)
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
![Page 9: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/9.jpg)
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);}
![Page 10: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/10.jpg)
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
![Page 11: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/11.jpg)
system/popen
● fork/exec (/bin/sh)● Security hole● Signal blocking
![Page 12: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/12.jpg)
Scheduling
● Time-sharing (timeslices)● States● Process table● Context switch● Priorities● Preemptive vs Cooperative Multitasking● Idle process
![Page 13: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/13.jpg)
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
![Page 14: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/14.jpg)
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);
![Page 15: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/15.jpg)
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);
![Page 16: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/16.jpg)
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; }
![Page 17: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/17.jpg)
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);
![Page 18: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/18.jpg)
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);
![Page 19: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/19.jpg)
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));
![Page 20: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/20.jpg)
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);
![Page 21: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/21.jpg)
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 */
...}
![Page 22: Sysprog 12](https://reader033.vdocuments.mx/reader033/viewer/2022052908/55961c4c1a28ab860e8b4585/html5/thumbnails/22.jpg)
IPC Intro
● Share data● Synchronize● Mutual Exclusion
– Critical region
– Semaphores