READ: P (admin); if (nw > 0 || nww > 0) {nrw++; V (admin); P (read);} nr++; if (nrw > 0) {nrw--; V (read);} else V (admin); READ THE DATABASE P (admin); nr--; if (nr==0 && nww > 0) {nww--; V (write);} else V (admin); WRITE P (admin); if (nr > 0 || nw > 0) {nww++; V (admin); P (write);} nw++; V (admin); WRITE TO THE DATABASE P (admin); nw--; if (nrw > 0) {nrw--; V (read);} else if (nww > 0) {nww--; V (write);} else V (admin); Only one thread uses the admin semaphore at the same time. Although semaphores are allowed to have any nonnegative value, not just zero or one, I'm not the semaphores to actually store anything meaningful, such as how many threads are waiting on them. I have variables for that. This gives me a lot more control over their operation. admin semaphore starts at 1, so that the first thread that P's it is allowed to use and won't block. The read and write semaphores start at 0, so the first thread that P's will block until a V is called. This is why we take care not to P these semaphores if there's no need to wait. If I swap lines 28 and 29, how is this solution to the readers/writers problem subtly different? "starvation": When a thread simply can't access a resource not because of deadlock but simply because the thread isn't being released due to other threads claiming the resource. This scheduling is system is not "fair." A "fair" system is one in which a waiting thread is guaranteed to be released sooner or later. This technique of releasing one reader, and that reader releasing one reader, and that reader releasing one reader, until all readers are released and THEN releasing the admin semaphore is called "passing the baton." This is not the only way to solve the readers/writers problem. (You could, for example, release all waiting readers in a loop.) However, this technique is very straightforward and once you get the hang of it, not too hard to implement. Your next programming assignment will involve semaphores and passing the baton to solve the problem. THE ROLLER COASTER PROBLEM We have one roller coaster car. It holds C people. When C people board the car, the car drives around the track and then C people disembark. The roller coaster does not run until it is full. There are n people at the theme park, n > C. Eventually, everyone is going to ride the roller coaster. If the car is moving, thye have to wait. If the car is full, they have to wait. If the car is not moving and not full, they can get on the car. When the ride is over, the C passengers on the car get off. (There may or may not be other people waiting.) When a passenger decides to ride the roller coaster, they wait in line. (They do not get to say "Ooh, line too long" and do something else.) So, other than the administrative semaphore, what semaphores do we need? What aspects of this problem require waiting? Semaphore: admin=1; board=0; car=0; unboard=0. Counters: nr=0; nrw=0; PASSENGER: P (admin); if (nr==C) {nrw++; V(admin);P(board);} //Now I need to board nr++; if (nr==C) { V (car); V (admin); } else if (nrw > 0) { nrw--; V (board);