94: Multithreading. The Race Is On.

Take Up Code - A podcast by Take Up Code: build your own computer games, apps, and robotics with podcasts and live classes

Categories:

Anytime a thread tries to access some memory or resource that another thread can change, you have a race condition. There is no winner for this kind of race. The whole application will lose. This episode describes first explains what a race condition is and then explains two ways to avoid race conditions. You can use atomic operations or critical sections. The problem that makes this type of bug difficult to catch is that you may not notice it. You could test your software and find no problems. After passing all the tests, you release it to the world. And that’s where the problems begin. You’ve just exposed your software to environments that are different than what you tested. You can use atomic operations if all you need to do is modify a single numeric value. Anything more complicated even if it’s a series of atomic operations will need a critical section to protect the entire sequence. Listen to the full episode or read the full transcript below. Transcript The problem that makes this type of bug difficult to catch is that you may not notice it all the time. Let’s compare this to real athletes and get a record holding olympian for our volunteer and the local high school running team that will be racing around town. Because we don’t want any cheating, nobody knows the directions for the race. Now it’s the job of the olympian to run around town and place instructions of where to run the race. Because olympians are faster than most people, this works great. By the time any of the high school runners reach a destination, they find instructions have already been placed and know where to go next. If this scenario represented your code, you could test it and find no problems. After passing all the tests, you release it to the world. And that’s where the problems begin. You’ve just exposed your software to environments that are different than what you tested. If one of those environments has a high school with a runner soon to be the fastest in the world, then when that runner reaches the first checkpoint, there won’t be any instructions yet. If you’re lucky, this will cause a crash. What? How is that lucky? Since when is a crash a good thing? Well, a crash is never a good thing. But the reason I say a crash is a good thing in this case is compared to the alternative. We can all agree that if the high school runner beats the olympian to the instructions, then the race should be cancelled. This is similar to a crash. What if instead, the high school runner reached the checkpoint ahead of the olympian and found what looked like valid instructions. If those instructions send the teenager someplace unknown, then we have a lot bigger problem than just a cancelled race. Now we have a missing child. That’s a lot worse. And relating this to computer programming, this would be like losing all your work because the application continued to run with bad information and corrupted your files not just in memory but on the hard drive too. You don’t even have an online backup because when the corrupt files were written to disk, your backup software kicked in and copied the bad files to your online storage and overwrote those too. Compare to this situation, a crash is much better. Now that you understand the stakes involved, I’ll explain more about avoiding race conditions right after this message from our sponsor. ( Message from Sponsor ) Going back to our make-believe race for a moment, how could we fix this? I mean fix it properly. Getting a faster olympian doesn’t really solve the problem. It just makes it even more harder to spot the problem. We need some way to fix race conditions for all cases. One good way is to avoid trying to modify anything that the threads need to access while the threads are running. If you can get everything ready before starting your threads, then your code will be fine. In the example, this would be like sending the olympian out to