[Python-ideas] [Python-Dev] GIL behaviour under Windows
Sturla Molden
sturla at molden.no
Thu Oct 22 05:09:44 CEST 2009
Sturla Molden skrev:
>
> However, David Beazley is not talking about Windows. Since the GIL is
> apparently not a mutex on Windows, it could behave differently. So I
> wrote a small script that contructs a GIL battle, and record how often
> a check-interval results in a thread-switch or not. For monitoring
> check intervals, I used a small C extension to read _Py_Ticker from
> ceval.c. It is not declared static so I could easily hack into it.
Anyway, if anyone wants to run a GIL battle, here is the code I used.
If it turns out the GIL is far worse with pthreads, as it is implemented
with a mutex, it might be a good idea to reimplement it with an event
object as it is on Windows.
Sturla Molden
----------------
In python:
from giltest import *
from time import clock
import threading
import sys
def thread(rank, battle, start):
while not start.isSet():
if rank == 0:
start.set()
try:
while 1:
battle.record(rank)
except:
pass
if __name__ == '__main__':
sys.setcheckinterval(1000)
print "check interval = %d" % sys.getcheckinterval()
for nthreads in range(1,7):
start = threading.Event()
battle = GIL_Battle(100000)
threads = [threading.Thread(target=thread, args=(i,battle,start))
for i in range(1,nthreads)]
for t in threads:
t.setDaemon(True)
t.start()
thread(0, battle, start)
for t in threads: t.join()
s,m = battle.report()
print "nthreads=%d, swiched=%d, missed=%d" % (nthreads, s, m)
In Cython or Pyrex:
from exceptions import Exception
cdef extern from *:
ctypedef int vint "volatile int"
vint _Py_Ticker
class StopBattle(Exception):
pass
cdef class GIL_Battle:
""" tests the fairness of the GIL """
cdef vint prev_tick, prev_rank, switched, missed
cdef int trials
def __cinit__(GIL_Battle self, int trials=100000):
self.prev_tick = _Py_Ticker
self.prev_rank = -1
self.missed = 0
self.switched = 0
self.trials = trials
def record(GIL_Battle self, int rank):
if self.trials == self.switched + self.missed:
raise StopBattle
if self.prev_rank == -1:
self.prev_tick = _Py_Ticker
self.prev_rank = rank
else:
if _Py_Ticker > self.prev_tick:
if self.prev_rank == rank:
self.missed += 1
else:
self.switched += 1
self.prev_tick = _Py_Ticker
self.prev_rank = rank
else:
self.prev_tick = _Py_Ticker
def report(GIL_Battle self):
return int(self.switched), int(self.missed)
More information about the Python-ideas
mailing list