Reputation: 9073
Look at this piece of code:
from threading import Thread
import time
cpt = 0
def myfunction():
print("myfunction.start")
global cpt
for x in range(10):
cpt += 1
time.sleep(0.2)
print("cpt=%d" % (cpt))
print("myfunction.end")
thread1 = Thread(target=myfunction)
thread2 = Thread(target=myfunction)
thread1.start()
thread2.start()
This is a very basic function which reads/write a global variable. I am running 2 threads on this same function.
I have read that python is not very efficient with multi-threading because of GIL, which automaticly locks functions or methods which access to the same resources. So, i was thinking that python will first run thread1, and then thread2, but i can see in the console output that the 2 threads are run in parallel. So i do not understand what gil is really locking...
Thanks
Upvotes: 0
Views: 118
Reputation: 140188
That's because of the sleep
system call which releases the CPU (and even "exits" from the interpreter for a while)
when you do time.sleep(0.2)
, the current thread is suspended by the system (not by Python) for a given amount of time, and the other thread is allowed to work.
Note that the print
statements or threading.current_thread()
that you could insert to spy the threads also yield (briefly) to the system so threads can switch because of that (remember Schrodinger's cat). The real test would be this:
from threading import Thread
import time
cpt = 0
def myfunction():
global cpt
for x in range(10):
cpt += 1
time.sleep(0.2)
print(cpt)
thread1 = Thread(target=myfunction)
thread2 = Thread(target=myfunction)
thread1.start()
thread2.start()
Here you get
20
20
which means that each thread worked to increase the counter in turn.
now comment the time.sleep()
statement, and you'll get:
10
20
which means that first thread took all the increasing, ended and let the second thread increase the further 10 counts. No system calls (even print
) ensure that the GIL works at full.
GIL doesn't induce a performance problem, it just prevents 2 threads to run in parallel. If you need to really run python code in parallel, you have to use the multiprocessing
module instead (with all its constraints, the pickling, the forking...)
Upvotes: 2