Async Techniques and Examples in Python Transcripts
Chapter: Course conclusion and review
Lecture: Review: Thread safety

Login or purchase this course to watch this video and the rest of the course contents.
0:00 Once you start working on threads, you need to be really careful about thread safety. One rule of thumb is share as little data
0:08 between threads as possible. That's not always possible or even useful. At the heart of this thread safety problem is
0:15 even normal functions, normal serial functions they have to take our program and evolve it from one state to another, and that often
0:23 means changing different parts of our program putting those all into some new state. In going through that process, there's no way
0:29 to avoid entering temporarily invalid states. So we have a function call, it's going to do a little work, it's going to change the state
0:37 of one of our objects, do a little more work change the state of another one of our objects and it's done, going to make some final changes
0:43 that make the entire system consistent again. So we start the function call, it goes through those transformations and then when we get
0:50 to the end, everything is good. So what's the problem? Remember, the problem is in serial code well, there is no problem.
0:57 But in concurrent code with threads, we could come along here, this thread could get suspended the other thread could come along and look
1:05 at that red object and the blue object at the bottom and say, "Oh, this must be what "the values are," and go and run with it.
1:11 Doesn't matter that it's put back. It's already used that to make a decision and it's off to the races to make a bad decision do something wrong.
1:18 So we must make sure when our apps go through this temporarily invalid state, other threads cannot come and see it.
1:24 We have to put up a little privacy wall. And so that's what thread safety is primarily about. So if we're going to do this, probably the best
1:31 way to work with is what's called a reentrant lock. So import threading, create a lock based on an RLock. Remember a regular lock is not reentrant.
1:38 That can be problematic, potentially. So we're using RLock and then we just say with that lock and then we do those potentially
1:46 unsafe operations, and by unsafe I mean we're entering into this temporarily invalid state. And we don't want other things to see it
1:52 so this with block, that's like our privacy wall for the data that we're manipulating. Once we get it all back in the right shape
1:58 we can release the lock and other parts of our app can go and work with it. So this is all great. Remember the other thing we spoke about was
2:05 if you're taking multiple locks at the same time if you take them in different orders you're going to end up in a deadlock, so you have to have
2:12 some mechanism to take locks in the same order all the time if you're taking multiple locks.

Talk Python's Mastodon Michael Kennedy's Mastodon