101: Multithreading. Signal And Wait.
Take Up Code - En podcast af Take Up Code: build your own computer games, apps, and robotics with podcasts and live classes
Kategorier:
Semaphores are often confused and characterized as just a more general form of a mutex. There’s actually some big differences though. I’m also going to explain some differences between the simple lock of the last episode and a mutex. Because you can declare a semaphore to only allow a single thread at a time to successfully wait on the semaphore, it’s often described as a more general purpose mutex. After all, a mutex can only ever allow a single thread to obtain the lock. But don’t be fooled by this similarity. Use a mutex when you want to guarantee exclusive access to a specific resource. And use a semaphore when you want to signal to some other threads that one or more resources are available. Another difference between how semaphores are used vs. how mutexes are used is in what operations are called. For a mutex, you have many different threads that each want to obtain the mutex so they each lock it. Only one of the threads will get the lock right away and the other threads will all block. Each thread that uses a mutex will call lock and then release in that order. Semaphores are not meant to be used like this. They also have two operations but there’s a good reason that the method names are different. With a semaphore, each thread needs to figure out which side it’s on and it should only call that one method. If a thread is making things available to other threads and needs to signal that something is ready, then it should call signal. And if a thread is waiting on something to be ready and then consuming items, then it should call wait. Just be aware that semaphores by themselves don’t actually protect specific resources. You’ll still want to use one or more mutexes for this purpose. Listen to the full episode for more explanation or read the full transcript below. Transcript Before we begin, I want to mention that some things in software don’t always have names or meanings that everybody agrees with. And some things are easy to get mixed up which can propagate this. I called the simple instruction that I described to implement locks a set and test instruction. Probably due to the way I think about it. And while some references also refer to it by this name, I think the more common name is the test and set instruction. It’s a minor point, but I wanted to mention it in case you wanted to read more about the topic. Today, we’re going to discuss semaphores and I’ll start out as usual with a description of a problem and then explain how you might use semaphores. Many adventure games have a similar concept of stamina. The hero usually has a limited supply of stamina and performing actions such as running will use up stamina while resting will restore stamina. This is just like how we get tired when running and sometimes need to catch our breath for a while by resting. The common programming name for this is the producer/consumer problem. It’s actually a little more difficult to solve properly than it might first appear. It’s easy to get into a race condition that can cause your application to think the stamina is full by the resting code and that the stamina is empty by the running code. Both sides think they can’t do anything and you have a form of a deadlock. Semaphores help with this but they’re a bit tricky to understand. A simple way to think of a semaphore is like a mutex that can count higher than one. But wait a minute, what exactly is a mutex? This is where we’re going to build a little more understanding from the previous episode about locks. If you haven’t already listened to episode 100, go ahead and do that now. Okay, in many ways a lock is similar to a mutex. Most languages and textbooks treat the terms interchangeably. I used the term lock in the last episode as a simple name for the concept of synchronizing access to a shared resource. The word mutex is just a shortened word made up from mutual exclusio