CS341: Operating System Lect20 : 16 th Sept 2014 Dr. A. Sahu Dept of Comp. Sc. & Engg. Indian Institute of Technology Guwahati Synchronization API of Pthread Mutex: lock, unlock, try_lock CondVar: wait, signal, signal_broadcast Synchronization Basic, Theory, Proof Hardware Support High level construct: Monitor Classical Problems of Synchronizations Code Data Files Registers Stack Thread Single threaded process Code Data Files Registers Registers Registers Stack Stack Stack Multi threaded process Thread #define NTH 10 pthread_mutex_t M = 0; void MutexCnt() { for(int i=0;i<10;i++) Lock( &M ); counter++; Unlock( &M); int counter = 0, i, j;; int main() { thread_t th[nth]; for(i=0; i < NTH; i++) thread_create(&th[i],null,mutexcnt,null); for(j=0; j < NTH; j++) { pthread_join( th[j], NULL); printf("final Ctr val: %d\n", counter); pthread_mutex_init, lock, unlock, trylock pthread_attr_setdetachstate, guardsize_np, stacksize,inheritsched, schedpolicy, schedparam pthread_cond_wait, signal, broadcast, init, destroy Our main concern Lock, unlock, trylock, condsignal, condbroadcast. spin lock CS critical section Resets lock upon exit 1
Earlier : Shared thread incrementing counter Train : One track many train MUTual EXclusion is must Train Collision Life loss Semaphore : A system of sending messages by holding The arms or two flags or poles in certain positions according to an alphabetic code Semaphore : A system of sending messages by holding The arms or two flags or poles in certain positions according to an alphabetic code Semaphore : A system of sending messages by holding The arms or two flags or poles in certain positions according to an alphabetic code Serialization points Minimize the size of critical sections Be careful Rather than wait, check if lock is available pthread_mutex_trylock trylock If already locked, will return EBUSY Will require restructuring of code Suspend self by pthread_yeild() Give chance to others Suspend self by doing a d wait.. 2
Processes/thread can execute concurrently May be interrupted at any, partially completing execution Concurrent access to shared data may result in data inconsistency Maintaining data consistency requires mechanisms to ensure the orderly execution of cooperating processes There is a buffer of size BUFFER_SIZE When a producer : produce an Item, he put into Buffer and increment the counter When a consumer : consume an Item, he read anitem from Buffer anddecrementdecrement the counter Initially, counteris set to 0 while(true) { /* produce an item in next produced */ while(counter == BUFFER_SIZE) ; /* do nothing */ buffer[in] = next_produced; in = (in + 1) % BUFFER_SIZE; counter++; while(true) { while(counter == 0) ; /* do nothing */ next_consumed= buffer[out]; out = (out + 1) % BUFFER_SIZE; counter ; /* consume the item in next consumed */ Assume that all the instruction are atomic The loadand store machine language instructions are atomic; Thatis,cannotbeinterrupted interrupted We will see: Still we have problem in Synchronization Or some protocol/algorithm to Handle We may need different hardware support, a specific kind of Instruction to be atomic 3
Counter ++ could be implemented as reg1 = counter reg1 = reg1 + 1 counter = reg1 Counter could be implemented as reg2 = counter reg2 = reg2 1 counter = reg2 Consider this execution interleaving with count = 5 initially: S0: producer execute reg1 = counter {reg1 = 5 S1: producer execute reg1 = reg1 + 1 {reg1 = 6 S2: consumer execute reg2 = counter {reg2 = 5 S3: consumer execute reg2 = reg2 1 {reg2 = 4 S4: producer execute counter = reg1 {counter = 6 S5: consumer execute counter = reg2 {counter = 4 Expected Result =5 Consider system of nprocesses {p 0, p 1, p n 1 Each process has critical section segment of code Process may be changing common variables, updating table, writing file, etc When one process in critical section, no other may be in its critical section Critical section problem is to design protocol to solve this Each process must ask permission to enter critical section in entry section, May follow critical section with exit section, then remainder section General structure of process P i do { entry section critical section exit section reminder section while (true) Lock () Unlock () Mutual Exclusion Progress Bounded Waiting Mutual Exclusion If process P i is executing in its CS Then no other processes can be executing in their CS Progress: Deadlock free If no process is running in its CS and there exist some processes that wish to enter their CS, Then the selection of the processes that will enter the CS next cannot be postponed indefinitely 4
Bounded Waiting : Starvation A bound must exist on the number of s that other processes are allowed to enter their CSs after a process has made a request toenteritscsandbeforethatrequestis that request is granted Assume that each process executes at a nonzero speed No assumption concerning relative speed of then processes Two approaches depending on if kernel is preemptive or non preemptive Preemptive allows preemption of process when running in kernel mode Non preemptive runs until exits kernel mode, blocks, or voluntarily yields CPU Essentially free of race conditions in kernel mode Absolute, true and mathematical, of itself and from its own nature, flows equably without relation to anything external. (I. Newton, 1689) Time is, like, Nature s way of making sure that everything doesn t happen all at once. (Anonymous, circa 1968) An event a 0 of thread A is Instantaneous No simultaneous events(breakties) ties) a 0 A threada is (formally) a sequence a 0, a 1,...of events Trace model Notation: a 0 a 1 indicates order a 0 a 1 a 2 5
Assign to shared variable Assign to local variable Invoke method Return from method Lots of other things Events are transitions a 3 a 2 a 0 a 1 Thread State Program counter Local variables System state Object fields (shared variables) Union of thread states Thread A Thread A Events of two or more threads Interleaved Notnecessarily independent(why?) Thread B 6
An interval A 0 =(a 0,a 1 ) is Time between events a 0 and a 1 b 0 B b 1 B 0 a 0 A 0 a 1 a 0 A 0 a 1 Interval A 0 precedes interval B 0 b 0 B 0 b 1 b 0 B b 1 B 0 a 0 A 0 a 1 a 0 A 0 a 1 Notation: A 0 B 0 Formally, End event of A 0 before start event of B 0 Also called happens before or precedes Remark: A 0 B 0 is just like saying 1066 AD 1492 AD, Middle Ages Renaissance, Oh wait, what about this week vsthis month? 7
NevertruethatA that A If A Bthen not true that B A If A B&B Cthen A C Funny thing: A B&B Amight both be false! Certain pairs of elements in the set, one of the elements precedes the other Irreflexive: NevertruethatA that A A Antisymmetric: If A Bthen not true that B A Transitive: If A B&B Cthen A C Linear order; a totally ordered set is also called a chain Also Irreflexive Antisymmetric Transitive Except that for every distinct A, B, Either A BorB A while (mumble) { a 0 ; a 1 ; a 0 k A 0 k k-th occurrence of event a 0 k-th occurrence of interval A 0 =(a 0,a 1 ) Let CSk i be thread i sk thcritical section execution Let CSk i be thread i sk thcritical section execution And CSm j be j sm thexecution 8
Let CSk i be thread i s k th critical section execution And CSm j be j s m th execution Then either or Let CSk i be thread i s k th critical section execution And CSm j be j s m th execution Then either or CS ik CS j m CS ik CS j m CS jm CS i k If some thread calls lock() And never returns Then other threads must complete lock()and unlock()calls infinitely often System as a whole makes progress Even if individuals starve If some thread calls lock() It will eventually return Individualthreadsmakeprogress 2 thread solutions first Illustrate most basic ideas Fits Fitson one slide Then n thread solutions class implements Lock { // thread-local index, 0 or 1 public void lock() { int i = ThreadID.get(); int j = 1 - i; Henceforth: i is current thread, j is other thread 9
class LockOne implements Lock { private bool [] flag=new bool [2]; public void lock() { int j,i=threadid.get();j=1-i; flag[i] = true; while (flag[j]) { public void unlock() { int i = ThreadID.get(); flag[i] = false; class LockOne implements Lock { private boolean[] flag = new boolean[2]; public void lock(){ int i = ThreadID.get(); int j = 1 - i; flag[i] = true; while (flag[j]) { Each thread has flag class LockOne implements Lock { private boolean[] flag = new boolean[2]; public void lock() { int i = ThreadID.get(); int j = 1 - i; flag[i] = true; while (flag[j]) { Set my flag class LockOne implements Lock { private boolean[] flag = new boolean[2]; public void lock() { int i = ThreadID.get(); int j = 1 - i; flag[i] = true; while (flag[j]) { Wait for other flag to become false Assume CS Aj overlaps CS B k Consider each thread's last (j thand k th) read and write in the lock() method before entering Derive a contradiction 10