In this chapter, we've delved deep into the workings of Python's native threading library. We've looked in depth at how we can effectively work with threads at a very granular level, and take full advantage of everything that the Python threading API has to offer.
We've looked at the numerous different thread types, and how they compare to each other. Not only that, but we've looked in detail at various concepts such as the multithreading model, and the numerous ways in which we can make user threads to their lower level siblings, the kernel threads.
In the next chapter, we'll dive into some of the key concurrency primitives that Python has on offer. Understanding these primitives will pave the way for us when it comes to making thread-safe programs that we can confidently push into production environments.