I want to release the GIL
"Martin v. Löwis"
martin at v.loewis.de
Tue Oct 21 16:32:51 EDT 2008
> When I run it, I notice that only one thread works and the other one
> never has a chance to run. I guess it is because the thread don't
> have a chance to release the GIL
This guess is wrong. A call to lock.acquire *does* release the GIL,
(as does the call to thread.sleep, as somebody else pointed out).
The real problem is that thread.lock is not guaranteed to be fair
(and isn't fair on most operating systems).
What happens is this (slight variations possible)
thread 1 thread 2
acquire GIL (wait for GIL)
release GIL (OS might schedule thread 2
here, but typically won't)
acquire lock
acquire GIL
print ident
release GIL
sleep acquire GIL
release GIL
(wait for lock) (still hold by thread 1)
(wait for GIL)
acquire GIL
release lock
release GIL
(wait for lock) (both threads waiting for
lock here. OS choses thread 1)
acquire lock
acquire GIL
(and so on)
To make that work the way you want it, you need a fair wake-up order.
Here is an example, using a list of Event objects:
import time
import threading
events = []
def f(e):
while True:
events.append(e)
token = e.wait()
e.clear()
print threading.currentThread()
time.sleep(1)
events.remove(e)
events[0].set()
for i in range(3):
t = threading.Thread(target=f, args=(threading.Event(),))
t.setDaemon(1)
t.start()
while not events:
print events
time.sleep(0.1)
events[0].set()
time.sleep(10)
HTH,
Martin
More information about the Python-list
mailing list