Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to correctly distinguish between Python threads

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces you how to correctly distinguish between Python threads, the content is very detailed, interested friends can refer to, hope to be helpful to you.

In the Python language, Python threads can compete with the main thread for GIL from here. In t_bootstrap, after applying for GIL, the child thread gets the GIL, which keeps the state object of the active thread all the time.

When the PyEval_AcquireThread ends, the child thread gets the GIL and is ready for all execution. The next child thread, through PyEval_ CallObjectWithKeywords, will eventually call PyEval_EvalFrameEx, which we are already familiar with.

The boot- > func passed into PyEval_CallObjectWithKeywords is a PyFunctionObject object, which is the compiled result of the threadProc defined in therad1.py. After the PyEval_CallObjectWithKeywords ends, the child thread releases the GIL and finishes all the work of destroying the thread. At this point, the child thread ends.

From the t_bootstrap code, it seems that the child thread will continue to execute until all the calculations of the child thread are completed before the GIL is released through the PyThreadState_DeleteCurrent. In this way, won't the main thread always be waiting for GIL? If this is the case, it is obviously impossible for Python threads to support multithreading.

In fact, in PyEval_EvalFrameEx, the analog clock interrupt maintained internally in Python shown in figure 15-2 constantly activates the thread's scheduling mechanism, constantly switching between the child thread and the main thread. In order to truly implement the multithreading mechanism, of course, we will analyze this in detail later. What we are interested in now is what the child threads are doing in PyEval_AcquireThreade.

At this point, knowing about PyEval_AcquireThread, it seems that the mechanism for creating threads is clear. But in fact, there is a very important mechanism-- the thread state protection mechanism-- hidden in an obscure place: PyThreadState_New.

[threadmodule.c] static PyObject* thread_PyThread_start_new_thread (PyObject* self, PyObject* fargs) {PyObject* func, * args, * keyw = NULL; struct bootstate * boot; long ident; PyArg_UnpackTuple (fargs, "start_new_thread", 2,3, & func, & args, & keyw); / / [1]: create bootstate structure boot = PyMem_NEW (struct bootstate, 1) Boot- > interp = PyThreadState_GET ()-> interp; boot- > funcfunc = func; boot- > argsargs = args; boot- > keywkeyw = keyw; / / [2]: initialize multithreaded environment PyEval_InitThreads (); / * Start the interpreter's thread-awareness * / / [3]: create thread ident = PyThread_start_new_thread (t_bootstrap, (void*) boot); return PyInt_FromLong (ident) [thread.c] / * Support for runtime thread stack size tuning. A value of 0 means using the platform's default stack size or the size specified by the THREAD_STACK_SIZE macro. * / static size_t _ pythread_stacksize = 0; [thread_nt.h] long PyThread_start_new_thread (void (* func) (void *), void * arg) {unsigned long rv; callobj obj; obj.id =-1; / * guilty until proved innocent * / obj.func = func; obj.arg = arg; obj.done = CreateSemaphore (NULL, 0,1, NULL) Rv = _ beginthread (bootstrap, _ pythread_stacksize, & obj); / * use default stacksize * / if (rv = = (unsigned long)-1) {/ / failed to create raw thread obj.id =-1;} else {WaitForSingleObject (obj.done, INFINITE);} CloseHandle ((HANDLE) obj.done); return obj.id;}

This mechanism is critical to understanding the creation and maintenance of Python threads. To analyze the protection mechanism of thread state, we first need to review the thread state. In Python, every Python thread has a thread state object associated with it.

In the thread state object, some information unique to each thread is recorded. In fact, we have seen this object when dissecting the initialization process of Python. The thread state object corresponding to each thread holds some information such as the thread's current PyFrameObject object and the thread's id. Sometimes, threads need to access this information.

For example, consider the simplest case where each thread needs to access the thread_id information stored in the thread state object. Obviously, thread A should get the thread_id of A, and so should thread B. If thread A gets the thread_id of B, that would be bad. This means that there must be a mechanism within the Python thread, which is very similar to the mechanism that the operating system manages processes.

We know that when the operating system switches from process A to process B, the context of process An is first saved and then switched; when switching from process B to process A, the context of process An is restored, which ensures that process An is always running in its own context.

The thread state object here is equivalent to the context of the process, and Python also has a mechanism for storing and restoring thread state objects. At the same time, within 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 Python schedules the thread, the thread state object corresponding to the activated thread will be assigned to _ PyThreadState_Current to keep the active thread state object all the time.

This leads to the question: how does Python get the state object corresponding to the activated thread when scheduling the process? Python internally manages the state objects of all Python threads through an one-way linked list, when you need to find a corresponding state object for a thread.

Analysis of the problem of first contact with Python deployment

Full parsing of powerful and fast Python operation language

Introduction to the rich resources of Python debugger

On the Summary of Python Interactive skills

How to correctly understand the Python source file

Just traverse the linked list and search for its corresponding state object. In the following description, we refer to this linked list as the "state object linked list". Let's take a look at the key data structures that implement this mechanism in Python, and access to this linked list of state objects does not have to be under the protection of GIL.

Because for this state object linked list, the Python thread creates a separate lock dedicated to protecting the state object linked list. PyThread_create_key will create a new key. Notice that the key here is all an integer, and when PyThread_create_key*** is called (the call in _ PyGILState_Init is *).

According to our previous analysis, this keymutex, like GIL, is actually a PNRMUTEX structure in which an Event kernel object under Win32 is maintained. The function of this keymutex is to mutually exclusive access to the linked list of state objects.

In _ PyGILState_Init, the new key created is received by the global variable autoTLSkey maintained by Python, where TLS is an acronym for Thread Local Store, and this autoTLSkey will be used as a parameter to the Python state object that holds all threads. Gets or sets the key value of That is, the key value in all key structures in the list of state objects will be autoTLSkey. Ah, the viewer said, you see, PyThread_create_key returns the incremented value of nkeys.

That is to say, every time you create, the result is different. How can you say that all key are the same? In fact, in the entire Python source code, PyThread_create_key is only called in _ PyGILState_Init, and this _ PyGILState_Init is called only once when the Python runtime environment is initialized.

On how to correctly distinguish between Python threads to share here, I hope that the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report