introduction
Before running this code cpu state
Status after operation
Run code results
python Understand the execution process of threads
encounter IO Will also release GIL
introductionWe often hear " because GIL The existence of ,python Multithreading cannot take advantage of multi-core CPU", Now let's not mention GIL,python Can we use multi-core cpu, Today I did an experiment , The code is simple as follows
while 1: pass
Before running this code cpu state Status after operation The following two figures show the status after operation , Of course, these are only two representative pictures , The screenshot interval is more than ten seconds
According to the first picture, we find cpu1、cpu3 The load of has increased significantly , We can figure out python Threads can utilize multiple cores cpu Conclusion , I always thought python Bind after running cpu One of the cores does not look like this now . The second picture is more interesting cpu2 It's full , Why is that ?
After thinking about it, it should be linux in cpu Affinity for processes leads to , This affinity is soft and not mandatory , This explains why there are many in the first picture cpu In the load .
ok In order to see more intuitively python Threads can utilize multiple cores cpu, Let's change the code , Look again in another way
import oswhile 1: print os.getpid() # Output process number
Run code results Be clear at a glance , Threads do switch on different cores .
Now let's look back at that classic sentence " because GIL The existence of ,python Multithreading cannot take advantage of multi-core CPU", This sentence is easy to understand GIL Will make python Run on a core , With today's example, let's re understand this sentence ,GIL It's the presence of the world that makes python Only one thread can be running at a time , There is no doubt about it , But it does not lock the thread or specify that it can only be in a cpu Up operation , Another thing I need to say is GIL It corresponds to the process , Each process has a GIL.
python Understand the execution process of threadsThreads ——> rob GIL——>CPU
This execution process leads to CPU Although intensive multithreaded programs can utilize multiple cores cpu Temporal single core cpu It's almost the same , And due to multiple threads grabbing GIL This link leads to operational efficiency <= Single thread .
Seeing this may give people an illusion , With GIL after python It's thread safe , It seems that thread locks are not needed at all , The actual situation is that the thread gets CPU Resources are not always implemented ,python The interpreter executes the thread 100 Bytecode ( Note that bytecode is not code ) Will release the thread GIL, If there is no lock at this time, other threads may modify the resources used by this thread ;
encounter IO Will also release GILAnother problem is to encounter IO Will also release GIL, The following are examples of these two situations
import threadinga = []def m1(): for _ in range(100000): a.append(1)def m2(): for _ in range(100000): a.append(2)def check(): """ Check a Is it orderly """ for i in range(len(a)): if i != 0: if a[i] < a[i-1]: print a[i-1], a[i] return False return Truet1 = threading.Thread(target=m1)t2 = threading.Thread(target=m2)t1.start()t2.start()t1.join()t2.join()print check()
expect 1111...22222..., The screenshot shows something different than expected
import threadingtext1 = '1' * 10000text2 = '2' * 10000def write(text): with open('test.txt', 'a') as f: f.write(text)def m1(): write(text1)def m2(): write(text2)t1 = threading.Thread(target=m1)t2 = threading.Thread(target=m2)t1.start()t2.start()t1.join()t2.join()
test.txt Screenshot
The final conclusion is , because GIL The existence of ,python Although multithreading can take advantage of multi-core CPU, But you can't make multiple cores work at the same time .
That's all python Multithread to multicore cpu Use the details of parsing , More about python Multithreading utilizes multiple cores cpu Please pay attention to other relevant articles of software development network !