How can we tell which Python thread corresponds to which State object? The first consideration is that we still have the thread ID. ID stores the ID of each thread. Based on these IDs, you can easily find the Python thread content.
The thread state object corresponding to each thread stores the current PyFrameObject object of this thread, and the thread id contains such information. Sometimes, threads need to access this information. For example, consider the simplest scenario, in some circumstances.
Each thread needs to access the thread_id information stored in the thread state object. Obviously, thread A should obtain the thread_id of thread A and thread B. If thread A obtains thread_id of thread B, it is A bad dish. This means that Python must have a set of internal mechanisms, which are similar to the operating system's mechanism for managing processes.
We know that when the operating system switches from process A to process B, the Context Environment of process A is saved and then switched. When process B switches back to process, the context of process A is restored, which ensures that process A is always running in its own context.
Here, the thread state object is equivalent to the context of the process. The Python thread content also has a mechanism to store and restore the thread state object. In Python, a global variable is maintained: PyThreadState * _ PyThread-State_Current.
The thread state object corresponding to the current active thread is saved in this variable. When the Python scheduling thread is executed, the thread state object corresponding to the activated thread is assigned to _ PyThreadState_Current, keep the status object of the active thread.
This raises the question: How does Python obtain the State object corresponding to the activated thread during process scheduling? Python internally manages the State objects of all Python threads through a one-way linked list. When you need to find a State object corresponding to a thread, traverse the linked list and search for its State object. In the subsequent description, the linked list is called the "State object linked list ".
Next, let's take a look at the key data structure to implement this mechanism. PyThread_create_key creates a new key. Note that the key here is an integer. In addition, when PyThread_create_key is called for the first time in _ PyGILState_Init), a keymutex is created through PyThread_allcate_lock.
According to our previous analysis, this keymutex is actually a PNRMUTEX struct like GIL, and maintains an Event kernel object under Win32 in this struct. The keymutex function is used to mutex access to the linked list of State objects.
In _ PyGILState_Init, the new key is received by the global variable autoTLSkey maintained by Python. TLS is short for Thread Local Store. This autoTLSkey is used as a parameter for saving state objects of all threads in Python, that is, the key value in Figure 15-6. That is to say, the key value in all the key struct in the status object list will be autoTLSkey.
Well, the reader said, you see that PyThread_create_key returns the incremental value of nkeys. That is to say, the results of every create operation are different, how can we say that all keys are the same? In fact, in the Python source code, PyThread_create_key is called only in _ PyGILState_Init, and this _ PyGILState_Init is called only once during Python runtime environment initialization.
Although the core function is called find_key, we can see that it is not only used for search, but also contains the action of creation. In [2] of code listing 15-3, find_key traverses the list of State objects and searches for key structures with matching keys and IDs.
If the search is successful, return directly. If the search fails, find_key creates a new key struct in [3] of code listing 15-3, and sets the id of the struct, key and value, and insert it to the header of the State object list.
In [1] and [4] of code listing 15-3, we can see that Python does not allow access to the list of State objects through the keymutex created in _ PyGILState_Init. After learning about this core function, the interface provided by the Python thread content for the State object list is very clear. In fact, it is a simple operation to insert, delete, and query linked lists.
- Python source code compilation skills
- Simple and Easy-to-use Python tools
- Introduction to the Python application field
- Python Android Object-Oriented Programming-Python applications
- How to Use the Python module to parse the configuration file?