After a Python sub-thread creates its own thread state object, it will put this object into the linked list of thread state objects through the _ PyGILState_NoteThreadState statement, the currently active Python subthreads do not necessarily obtain GIL.
In thread1.py, the main thread now obtains GIL, but the subthread has not applied for GIL yet, and naturally it will not suspend itself. The main thread and subthread are both Win32 native threads. Therefore, the operating system may switch between the main thread and the Python sub-thread. Here we should emphasize that the thread scheduling at the operating system level is different from that at the Python level.
Python-level thread scheduling must mean that GIL has the authority, while the operating system-level thread scheduling does not necessarily mean that GIL is easy to handle. After all the threads have completed initialization. The thread scheduling of the operating system is the same as that of Python. At that time, the Python thread scheduling will force the current active thread to release GIL, and this operation will trigger the Event Kernel Object maintained in GIL.
This trigger triggers the thread scheduling of the operating system. Before the thread Initialization is complete, there is no such causal relationship between Python thread scheduling and the operating system thread scheduling. It shows the role of GIL as a bridge between Python-level thread scheduling and operating system-level thread scheduling.
We have analyzed the PyEval_AcquireThread code before. In PyEval_AcquireThread, the sub-thread makes the final sprint. To survive and execute it, it starts to fight for GIL through PyThread_acquire _ lock. In this step.
The Python sub-thread suspends itself, and the thread scheduling mechanism of the operating system can no longer wake up by its own strength. Only after the Python thread scheduling mechanism forces the main thread to give up GIL. The sub-thread will be awakened. After the sub-thread is awakened, the main thread is stuck in waiting, and it is also struggling to watch the moment that Python forces the sub-thread to give up GIL.
After a subthread is awakened by the Python thread scheduling mechanism, the first thing it does is to set the current thread state object maintained by Python to its own State object through PyThreadState_Swap, it is the same as restoring the Context Environment of the operating system process.
Now our Python sub-thread is waiting for GIL, but note that the initialization of the thread is not completed yet, because the sub-thread has not smoothly entered the bytecode interpreter. After the Python thread is scheduled to wake up the Sub-thread. The sub-thread will return to t_bootstrap.
And enter PyEval_CallObjectWithKeywords. Keep moving forward from here, and finally call PyEval_EvalFrameEx to enter the interpreter. At that time, the Python sub-thread was completely controlled by the Python thread scheduling mechanism, just like the main thread.
It should be noted that PyThread_start_new_thread is executed in the main thread, and from bootstrap, it is executed in the Child thread. The action involving thread destruction, such as PyThreadState _ DeleteCurrent, will be analyzed in the subsequent sections. At this point, readers may have some doubts. It seems useless to spend a lot of time analyzing the linked list of thread state objects. In fact, this is not the case. Think about it when Thread Scheduling occurs.
At the Python level, you need to use the previously analyzed PyTrheadState_Swap function to switch the current thread state object. In this case, you need to obtain the thread object from the linked list of the thread state object based on the thread id. In fact, many APIs in Python, such as PyGILState_Ensure, involve this linked list. These APIs may be called in large quantities during interaction between C and Python, interested readers can explore it in depth.
- 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?