first about single-threaded, multi-threaded, multi-process in PythonCPUthe utilization is measured as follows:
Single threaded, multi-threaded, multi-process test code uses a dead loop.
1) Single Thread:
2) Multithreading:
3) Multi-process:
ViewCpuUse efficiency:
beginning to observe the separate execution timeCpuefficiency of Use:1) When a single thread executes:
2) When multithreading is performed:
3) When multiple processes are executed:
Summary: 1) Single-process one-way, the utilization of the dual-core CPU can only use one core, not the full use of two cores. 2) Single-process multi-threaded, for the dual-core CPU, although the two cores are used, but it is clear that the two cores are not fully utilized, here is the concept of a Gil (Global interpreter Lock): Gil is different from the mutex between threads, Gil is not a python feature, But a concept introduced by CPython. (Jpython,pypy) PythonThe code consists ofPythonThe Interpreter execution (CPython). So when will our code bepythoninterpreter execution, by ourGILThat is, the global interpreter lock is controlled. when we have a thread that starts to access the interpreter,GILlocks the lock, which means that other threads can no longer access the interpreter, meaning that other threads cannot be executed again.
Gil Execution Process:
- Locking Gil.
- Switch to a thread to execute.
- Run.
- Unlock GIL.
repeat the above steps again. the execution flow for the following code Gil:
Import Threadingimport time# Write two functions, let two threads to execute # Two functions, each to access my global variable number = 0def test1 (count): Global number for i In range (count): number + = 1 print (number) def test2 (count): Global number for I in range (count): Number + = 1 print (number) def main (): Th1 = Threading. Thread (target=test1,args= (1000000,)) Th2 = Threading. Thread (Target=test2, args= (1000000,)) Th1.start () Th2.start () time.sleep (5) print (number) if __name__ = = ' __main__ ': Main ()
The result of the operation (here is a full description of the multithreading resource preemption problem):
The flowchart is as follows:
Thread 1 executes to add an action to the global variable when the global interpreter lock is retracted, thread 2 requests and gets the global interpreter lock to start running, the global variable is modified and the global interpreter lock is freed after the add operation is completed on line 2. At this point, thread 1 gets the global interpreter lock again, starting from the last time the global interpreter lock was released to continue the operation of adding a global variable, remember that the global variable in thread 1 is still the beginning of 0, although thread 2 has been Gay operation, but thread 1 does not know, Thread 1 is still the last position to start execution, so thread 1 at the end of the implementation of the addition of the 1 again assigned to the global variable num, that is, thread 2 after the completion of the addition of an operation after the assignment of the past 1 is the thread 1 is assigned to the past 1 is overwritten, added two times is added! Similar to the co-process, just do a code to switch back and forth operation!
So in Python , only one thread can be executed at the same time. So multithreading in Python is fake . Since then why do we use multithreading? In fact, multithreading also has its advantages, such as when we are in the IO operation, the effective organization of the program blocking, not always waiting indefinitely. 3) Multi-process, for the dual-core CPU, each process priority is equal, the allocation of resources is equal, two processes can fully utilize the dual-core CPU, and because the compute-intensive task relies solely on the CPU's core number, it is necessary to fully utilize the CPU, At this time the benefits of multi-process can be perfectly reflected.
Single-threaded, multi-threaded, multi-process CPU utilization measurements in Python and Gil principle analysis