1 / 12

Controlling concurrency

Controlling concurrency. A look at some techniques for process synchronization in the Linux environmemt. What is a ‘race condition’ ?.

zada
Download Presentation

Controlling concurrency

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Controlling concurrency A look at some techniques for process synchronization in the Linux environmemt

  2. What is a ‘race condition’ ? • Without any ‘synchronization’ mechanism, multiprogramming is vulnerable to ‘races’ in which programs produce unpredictable and erroneous results, due to the relative timing of instruction-execution in separate threads or processes • An example program demonstrates this phenomenon (see our ‘racedemo.cpp’)

  3. Two tasks write to one terminal • A parent-process forks a child-process, and both write messages to the screen, but without coordinating their efforts • The operating system’s task-scheduler repeatedly preempts each of them • The result is incomprehensible gibberish! • Programs like this one are said to contain a ‘race condition’

  4. The cure is communication • What’s needed is some way for the tasks to be made aware of each other’s actions • Various mechanisms for this exist in Linux • One of the simplest ways is by ‘signaling’ (i.e., one task can wait for an ‘all clear’ signal to be sent to it by the other task) • But ‘busy-waiting’ needs to be avoided, since it wastes CPU time and degrades the overall efficiency of the system

  5. The ‘signal mask’ • Each process has a ‘signal mask’ that can be used to ‘block’ certain specific signals • The signal mask for each process is kept in its process control block (in the kernel) • But a process can inspect and modify its signal mask by using special system-calls

  6. The ‘sigset_t’ type struct task_struct Process Control Block The signal mask is a collection of flag-bits that indicates which signals are to be ‘blocked’ sigset_t blocked

  7. How to inspect ‘signal mask’ • 1. Include the <signal.h> header-file: #include <signal.h> • 2. Declare a ‘sigset_t’ object: sigset_t sigmask; • 3. Call the ‘sigprocmask()’ library-function: sigprocmask( 0, NULL, &sigmask );

  8. How to modify ‘signal mask’ • 1. Declare two ‘sigset_t’ objects: sigset_t nset, oset; • 2. Initialize the ‘new’ signal-set: sigemptyset( &nset ); sigaddset( &nset, SIGUSR1 ) sigaddset( &nset, SIGUSR2 ) • 3. Call the ‘sigprocmask()’ library-function: sigprocmask( SIG_BLOCK, &nset, &oset );

  9. How to wait for a signal • 1. Declare and initialize a global variable: int done = 0; • 2 Define your signal-handling function: void upon_signal( int signum ) { done = 1; }. • 3. Install your signal-handler function: signal( SIGUSR1, upon_signal ); signal( SIGUSR2, upon_signal ); • 4. Declare and initialize a ‘sigset_t’ object: sigset_t zeromask; sigemptyset( &zeromask ); • 5. Then use ‘sigsuspend()’ to wait for your signal: while ( done == 0 ) sigsuspend( &zeromask );

  10. Our ‘racecure.cpp’ demo • These signal-handling library-functions are used by this demo-program to remove the ‘race condition’ without doing busy-waiting • It’s based on ideas of W. Richard Stevens from his classic: “Advanced Programming in the UNIX Environment” (1993).

  11. How it works parent-process child-process done done signal-handler signal-handler write-message; TELL_CHILD; WAIT_CHILD; WAIT_PARENT; write-message; TELL_PARENT; SIGUSR1 SIGUSR2 user kernel signal-mask signal-mask

  12. In-class exercises • Modify ‘racedemo’ so that the parent forks twice (i.e., two child-processes), with three processes all writing to the ‘stdout’ stream • Then add synchronization functions which will eliminate the race conditions and allow the parent-process to finish writing before either of the child-processes begins

More Related