[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-Dev mailing list

AltStyle によって変換されたページ (->オリジナル) /