CS 241 Section Week - PowerPoint PPT Presentation

1 / 46
About This Presentation
Title:

CS 241 Section Week

Description:

CS 241 Section Week – PowerPoint PPT presentation

Number of Views:70
Avg rating:3.0/5.0
Slides: 47
Provided by: Alej198
Category:
Tags: argv | section | week

less

Transcript and Presenter's Notes

Title: CS 241 Section Week


1
CS 241 Section Week 9(10/23/08)
2
Outline
  • MP5 preview
  • Signals
  • Threads
  • pause(), sigwait()
  • POSIXTMR timers
  • Memory

3
MP5 Preview
4
MP5 Preview
  • For success on this MP
  • Carefully read Readme.txt for details!
  • We provide you with some in built-in test cases
    so you can see whether your implementation is
    correct.
  • Requires a good understanding of concepts of Unix
    process and signal handling ( fork(), exec(),
    wait() )
  • Good luck!

5
Signals
6
Signals
  • A signal is a software notification to a process
    of an event.
  • Signals are asynchronous, so the process can
    handle them no matter where it is in the program.

7
User-triggered signals
  • CtrlC triggers SIGINT
  • CtrlZ triggers SIGSTOP
  • CtrlD triggers SIGQUIT
  • etc.
  • Run stty -a to see others.

8
Sending signals from the command line
  • The Unix kill command sends signals.
  • The usage is
  • kill -ltsignalgt ltpidgt
  • Run kill -l to see available signals.
  • The command is called kill because in many cases
    the default behavior is for the process receiving
    the signal to die.

9
Sending signals from inside the program
  • Use the kill() function to send signals from one
    process to another.
  • include ltsys/types.hgt
  • include ltsignal.hgt
  • int kill(pid_t pid, int sig)
  • Examples
  • kill(getpid(),SIGTERM)
  • kill(getppid(),SIGKILL)

10
  • include ltstdio.hgt
  • include ltsys/types.hgt
  • include ltsignal.hgt
  • int shift 1
  • int main(int argc, char argv)
  • char c
  • while(1)
  • c getchar()
  • if (cgt'a' c lt 'z')
  • c shift
  • while (c gt 'z')
  • c - 26
  • else if (cgt'A' c lt 'Z')
  • c shift
  • while(c gt 'Z')
  • c - 26
  • putchar(c)
  • This example takes in input one character at a
    time, and shifts the letters forward by one.
  • If you run this program you can
  • Send it signals using CtrlC, CtrlZ, etc.
  • The kill command, from another window

11
Signal blocking
  • We can block some signals, so they dont reach
    the process right away.
  • The calls used are
  • sigemptyset(newsigset)
  • sigaddset(newsigset,SIGINT)
  • sigprocmask(SIG_BLOCK,newsigset,NULL)

12
  • include ltstdio.hgt
  • include ltsys/types.hgt
  • include ltsignal.hgt
  • int shift 1
  • int main(int argc, char argv)
  • char c

Blocking SIGINT.
sigset_t newsigset // Turn off SIGINT if
(sigemptyset(newsigset) -1)
perror("Can't set new mask.") else
if (sigaddset(newsigset,SIGINT) -1)
perror("Can't set signal set.")
else if (sigprocmask(SIG_BLOCK,newsigset,NULL)
-1) perror("Can't block INT signal.")

while(1) c getchar() if (cgt'a' c lt
'z') c shift while (c gt
'z') c - 26 else if (cgt'A' c
lt 'Z') c shift while(c gt
'Z') c - 26 putchar(c)
  • This program does not respond to CtrlC. You
    will need to send it a SIGKILL signal to kill it,
    because the SIGINT signal has been blocked
  • (Note some signals, such as SIGKILL, cannot be
    blocked.)

13
Signal sets
  • A sigset_t is a set of signals, represented as a
    bit array.
  • The functions sigemptyset, sigfillset, sigaddset,
    and sigdelset set and change the signal set.

14
Signal Mask
  • The signal mask is the set of signals that are
    currently blocked. sigprocmask changes the
    signal mask
  • sigprocmask(SIG_BLOCK,newset,oldset) blocks all
    signals in newset.
  • sigprocmask(SIG_UNBLOCK,newset,oldset) unblocks
    all signals not in newset.
  • sigprocmask(SIG_SETMASK,newset,oldset) blocks
    all signals in newset, and unblocks all signals
    not in newset.

15
include ltstdio.hgt include ltsys/types.hgt include
ltsignal.hgt int shift 1
static void change_shift(int sig) shift
We can change what happens when a process
receives a signal.
  • int main(int argc, char argv)
  • struct sigaction act
  • sigset_t newsigset
  • char c
  • // Turn off SIGINT
  • if (sigemptyset(newsigset) -1)
    perror("Can't set new mask.")
  • else if (sigaddset(newsigset,SIGINT)
    -1)
  • perror("Can't set signal set.")
  • else if (sigprocmask(SIG_BLOCK,newsigset
    ,NULL) -1)
  • perror("Can't block INT signal.")

// Add hadler for SIGUSR1 act.sa_handler
change_shift act.sa_flags 0 if(sigemptyset(ac
t.sa_mask) 1 sigaction(SIGUSR1, act,
NULL)-1) perror("Can't set SIGUSR1
handler") return -1
while(1) c getchar() if (cgt'a' c lt
'z') c shift while (c gt
'z') c - 26 else if (cgt'A' c
lt 'Z') c shift while(c gt
'Z') c - 26 putchar(c)
  • Every time the process receives the signal
    SIGUSR1, it calls the change_shift function,
    which changes the shift value.
  • act.sa_handler change_shift
  • act.sa_flags 0
  • sigemptyset(act.sa_mask)
  • sigaction(SIGUSR1, act, NULL)

16
Signal Actions
  • In the struct sigaction act
  • sa_handler is the function called upon receiving
    the signal
  • sa_flags are special flags
  • sa_mask are the additional signals to block while
    handling this signal
  • sigaction(SIGUSR1, act1, NULL) associates this
    handler with SIGUSR1.

17
Summary SIGNALS
  • Asynchronous notification to a process indicating
    some action should be taken
  • Sending signals to a process
  • kill -ltsignalgt ltpidgt
  • int kill(pid_t pid, int sig)
  • We can signal individual threads, too
  • int pthread_kill(thread_t tid, int sig)

18
Process Signal Masks
  • Setting SIGINT to be blocked
  • if ((sigemptyset(set) -1)
  • (sigaddset(set, SIGINT) -1))
  • perror(Failed init signal set)
  • else if
  • (sigprocmask(SIG_BLOCK, set, oldset) -1)
  • perror(Failed to block SIGINT)
  • SIG_BLOCK adds set to current mask
  • oldset will store the previous signal mask

19
Threads
20
Thread Signal Masks
  • pthread_sigmask()
  • Takes same parameters as sigprocmask
  • Only affects the signal mask of a single thread
  • Signal mask is inherited on thread creation

21
  • void handler(int sig)
  • pthread_exit(NULL)
  • void hello_thread(void arg)
  • // this thread should exit on SIGUSR1
  • for ()
  • printf("Hello\n")
  • sleep(5)
  • return NULL
  • void world_thread(void arg)
  • // this thread should exit on SIGUSR2
  • for ()
  • printf("World\n")
  • sleep(5)
  • return NULL

How can you change the code to stop the hello
thread when receiving SIGUSR1 and the world
thread when receiving SIGUSR2 ?
22
  • void handler(int sig)
  • pthread_exit(NULL)
  • void hello_thread(void arg)
  • // this thread should exit on SIGUSR1
  • for ()
  • printf("Hello\n")
  • sleep(5)
  • return NULL
  • void world_thread(void arg)
  • // this thread should exit on SIGUSR2
  • for ()
  • printf("World\n")
  • sleep(5)
  • return NULL

How can you change the code to stop the hello
thread when receiving SIGUSR1 and the world
thread when receiving SIGUSR2 ?
  • Hint 1 you should not have to change the signal
    handler
  • Hint 2 what about the main thread?

23
  • void handler(int sig)
  • pthread_exit(NULL)
  • void hello_thread(void arg)
  • // this thread should exit on SIGUSR1
  • for ()
  • printf("Hello\n")
  • sleep(5)
  • return NULL
  • void world_thread(void arg)
  • // this thread should exit on SIGUSR2
  • for ()
  • printf("World\n")
  • sleep(5)
  • return NULL

void handler(int sig) pthread_exit(NULL) voi
d hello_thread(void arg)
// unblock SIGUSR1 for this thread sigset_t
set sigemptyset(set) sigaddset(set,
SIGUSR1) pthread_sigmask(SIG_UNBLOCK, set,
NULL)
for () printf("Hello\n") sleep(5)
return NULL void world_thread(void arg)
// unblock SIGUSR2 for this thread sigset_t
set sigemptyset(set) sigaddset(set,
SIGUSR2) pthread_sigmask(SIG_UNBLOCK, set,
NULL)
for () printf("World\n") sleep(5) r
eturn NULL int main(int argc, char
argv) pthread_t hello, world struct
sigaction act act.sa_flags 0 act.sa_handler
handler sigemptyset(act.sa_mask) sigaction(
SIGUSR1, act, NULL) sigaction(SIGUSR2, act,
NULL)
// block SIGUSR1 and SIGUSR2 for all three
threads sigset_t set sigemptyset(set) sigadd
set(set, SIGUSR1) sigaddset(set,
SIGUSR2) sigprocmask(SIG_BLOCK, set, NULL)
pthread_create(hello, NULL, hello_thread,
NULL) pthread_create(world, NULL,
world_thread, NULL) pthread_join(hello,
NULL) pthread_join(world, NULL) return
EXIT_SUCCESS
24
Signal Handlers
  • Allow us to change what happens when a signal is
    received
  • void handler(int signo)
  • struct sigaction act
  • act.sa_flags 0
  • act.sa_handler handler
  • // additional signals blocked in the handler
  • sigemptyset(act.sa_mask)
  • sigaction(SIGUSR1, act, NULL)

25
sa_handler vs. sa_sigaction
  • We can get additional information about the
    signal
  • void handler(int signo, siginfo_t info, void
    context)
  • act.sa_flags SA_SIGINFO
  • // fill sa_sigaction instead of sa_handler
  • act.sa_sigaction handler
  • Extra information contains, e.g., the source of
    the signal (info-gtsi_code)
  • SI_USER user-created signal (with abort, kill,
    etc.)
  • SI_TIMER a POSIXRTS timer expired
  • etc.

26
void handler(int sig, siginfo_t info, void
context) // handle SIGINT exit(EXIT_SUCCESS)
int main(int argc, char argv) int
n // set up SIGINT to call handler() for
() count 0 printf("tick\n") // we
sleep in a loop since it can be interrupted by
SIGINT n 5 do n sleep(n) while
(n gt 0) return EXIT_SUCCESS
  • Windows users will sometimes press Ctrl-C (for
    copy to clipboard), inadvertently killing a UNIX
    process.
  • Lets change the SIGINT handler to kill the
    process only if the user really means it!
  • i.e., presses Ctrl-C three times within a
    5-second tick
  • And lets only count signals sent by the kernel
    (based on keyboard input)
  • info-gtsi_code SI_KERNEL

27
void handler(int sig, siginfo_t info, void
context) // handle SIGINT exit(EXIT_SUCCESS)
int main(int argc, char argv) int
n // set up SIGINT to call handler() for
() count 0 printf("tick\n") // we
sleep in a loop since it can be interrupted by
SIGINT n 5 do n sleep(n) while
(n gt 0) return EXIT_SUCCESS
int count 0
void handler(int sig, siginfo_t info, void
context)
// handle SIGINT if (info-gtsi_code SI_KERNEL
count gt 3) printf("Exiting by user's
request\n") exit(EXIT_SUCCESS)
int main(int argc, char argv) int n
struct sigaction act act.sa_flags
SA_SIGINFO act.sa_sigaction
handler sigemptyset(act.sa_mask) sigaction(SI
GINT, act, NULL)
for () count 0 printf("tick\n") n
5 // sleep in a loop since it can be
interrupted by SIGINT do n sleep(n)
while (n gt 0) return EXIT_SUCCESS
28
pause(), wait()
29
pause()
  • Waits for any signal that is not blocked/ignored
  • But if a signal is generated before pause() is
    called, pause() will never see it
  • If we use the sigmask to block the signal until
    pause() is called, it will be queued until we
    remove it
  • However, pause() will just sit there waiting for
    the signal that is blocked it will never check
    the queue
  • In summary pause() only returns if called before
    the signal is generated!

30
sigwait()
  • Takes as parameter a sigset corresponding to
    which signals it should wait for
  • You should block the signals first
  • sigwait() will remove a signal from the queue
    that is in its sigset
  • Must also pass a pointer to an integer for it to
    store signal that was removed
  • sigwait(sigset_t set, int signo)

31
Counting signals
include ltstdio.hgt include ltstdlib.hgt include
ltunistd.hgt include ltsys/types.hgt include
ltsignal.hgt int main(int argc, char
argv) int signalcount 0 // block
SIGUSR1 and SIGUSR2 printf("waiting for
signals\n") for () // wait for a signal
instead of sleeping sleep(100) signalcount
printf("signals so far d\n",
signalcount) return EXIT_SUCCESS
32
  • Use sigwait() to count how many times a process
    receives SIGUSR1 or SIGUSR2
  • Dont forget to block them first!

include ltstdio.hgt include ltstdlib.hgt include
ltunistd.hgt include ltsys/types.hgt include
ltsignal.hgt int main(int argc, char
argv) int signalcount 0 // block
SIGUSR1 and SIGUSR2 printf("waiting for
signals\n") for () // wait for a signal
instead of sleeping sleep(100) signalcount
printf("signals so far d\n",
signalcount) return EXIT_SUCCESS
33
include ltstdio.hgt include ltstdlib.hgt include
ltunistd.hgt include ltsys/types.hgt include
ltsignal.hgt int main(int argc, char argv)
include ltstdio.hgt include ltstdlib.hgt include
ltunistd.hgt include ltsys/types.hgt include
ltsignal.hgt int main(int argc, char
argv) int signalcount 0 // block
SIGUSR1 and SIGUSR2 printf("waiting for
signals\n") for () // wait for a signal
instead of sleeping sleep(100) signalcount
printf("signals so far d\n",
signalcount) return EXIT_SUCCESS
int signalcount 0 sigset_t sigset int
signo // block SIGUSR1 and SIGUSR2 sigemptyset
(sigset) sigaddset(sigset, SIGUSR1) sigaddse
t(sigset, SIGUSR2) sigprocmask(SIG_BLOCK,
sigset, NULL)
printf("waiting for signals\n") for ()
if (sigwait(sigset, signo) -1)
perror("Failed to wait using
sigwait") return EXIT_FAILURE
signalcount printf("signals so far
d\n", signalcount) return EXIT_SUCCESS
34
POSIX TMR Timers
35
POSIXTMR timers
  • They are in charge of
  • Sending the SIGALRM signal to the process
  • If we set up a signal handler for SIGALRM, we
    have a programmable timer!
  • Signals sent for timers or interrupts need to be
    unblocked for the thread that will be receiving
    them!!!

36
Memory
37
Memory
  • Contiguous allocation and compaction
  • Paging and page replacement algorithms

38
Contiguous Allocation
  • Memory is allocated in monolithic segments or
    blocks
  • Public enemy 1 external fragmentation
  • We can solve this by periodically rearranging the
    contents of memory

39
Compaction
  • After numerous malloc() and free() calls, our
    memory will have many holes
  • Total free memory is much greater than that of
    any contiguous chunk
  • We can compact our allocated memory
  • Shift all allocations to one end of memory, and
    all holes to the other end
  • Temporarily eliminates of external fragmentation

40
Compaction (example)
  • Lucky that A fit in there! To be sure that there
    is enough space, we may want to compact at (d),
    (e), or (f)
  • Unfortunately, compaction is problematic
  • It is very costly. How much, exactly?
  • How else can we eliminate external fragmentation?

41
Summary Paging
  • Divide memory into pages of equal size
  • We dont need to assign contiguous chunks
  • Internal fragmentation can only occur on the last
    page assigned to a process
  • External fragmentation cannot occur at all
  • Need to map contiguous logical memory addresses
    to disjoint pages

42
Summary Virtual Memory
  • RAM is expensive (but fast), disk is cheap (but
    slow)
  • Need to find a way to use the cheaper memory
  • Store memory that isnt frequently used on disk
  • Swap pages between disk and memory as needed
  • Treat main memory as a cache for pages on disk

43
Page Replacement
  • We may not have enough space in physical memory
    for all pages of every process at the same time.
  • But which pages shall we keep?
  • Use the history of page accesses to decide
  • Also useful to know the dirty pages

44
Page Replacement Strategies
  • It takes two disk operations to replace a dirty
    page, so
  • Keep track of dirty bits, attempt to replace
    clean pages first
  • Write dirty pages to disk during idle disk time
  • We try to approximate the optimal strategy but
    can seldom achieve it, because we dont know what
    order a process will use its pages.
  • Best we can do is run a program multiple times,
    and track which pages it accesses

45
Page Replacement Algorithms
  • Optimal last page to be used in the future is
    removed first
  • FIFO First in First Out
  • Based on time the page has spent in main memory
  • LRU Least Recently Used
  • Locality of reference principle again
  • MRU most recently used removed first
  • When would this be useful?
  • LFU Least Frequently Used
  • Replace the page that is used least often

46
Example
  • Physical memory size 4 pages
  • Pages are loaded on demand
  • Access history 0 1 2 3 4 0 1 2 3 4
  • Which algorithm does best here?
  • Access history 0 1 2 3 4 4 3 2 1 0
  • And here?
Write a Comment
User Comments (0)
About PowerShow.com