如何使用threading.Events:
import threadingimport timeimport logginglogger=logging.getLogger(__name__)def f(resume,is_waiting,name): while True: if not resume.is_set(): is_waiting.set() logger.debug('{n} pausing...'.format(n=name)) resume.wait() is_waiting.clear() logger.info(name) time.sleep(1)def h(resume,waiters): while True: logger.debug('halt') resume.clear() for i,w in enumerate(waiters): logger.debug('{i}: wait for worker to pause'.format(i=i)) w.wait() logger.info('h begin') time.sleep(2) logger.info('h end') logger.debug('resume') resume.set() time.sleep(5)logging.basicConfig(level=logging.DEBUG, format='[%(asctime)s %(threadName)s] %(message)s', datefmt='%H:%M:%S')# set means resume; clear means haltresume = threading.Event()resume.set()waiters=[]for name in 'fg': is_waiting=threading.Event() waiters.append(is_waiting) threading.Thread(target=f,args=(resume,is_waiting,name)).start() threading.Thread(target=h,args=(resume,waiters)).start()
产量
[07:28:55 Thread-1] f[07:28:55 Thread-2] g[07:28:55 Thread-3] halt[07:28:55 Thread-3] 0: wait for worker to pause[07:28:56 Thread-1] f pausing...[07:28:56 Thread-2] g pausing...[07:28:56 Thread-3] 1: wait for worker to pause[07:28:56 Thread-3] h begin[07:28:58 Thread-3] h end[07:28:58 Thread-3] resume[07:28:58 Thread-1] f[07:28:58 Thread-2] g[07:28:59 Thread-1] f[07:28:59 Thread-2] g[07:29:00 Thread-1] f[07:29:00 Thread-2] g[07:29:01 Thread-1] f[07:29:01 Thread-2] g[07:29:02 Thread-1] f[07:29:02 Thread-2] g[07:29:03 Thread-3] halt
(针对评论中的问题)此代码尝试测量
h-thread从其他工作线程获取每个锁所花费的时间。
似乎表明,即使
h正在等待获取锁,另一个工作线程也可能以相当高的概率释放并重新获取锁。没有优先权
h只是因为它等待了更长的时间。
David
Beazley在PyCon上介绍了有关线程和GIL的问题。这是幻灯片的pdf格式。这是一本引人入胜的书,也可能有助于解释这一点。
import threadingimport timeimport logginglogger=logging.getLogger(__name__)def f(lock,n): while True: with lock: logger.info(n) time.sleep(1)def h(locks): while True: t=time.time() for n,lock in enumerate(locks): lock.acquire() t2=time.time() logger.info('h acquired {n}: {d}'.format(n=n,d=t2-t)) t=t2 t2=time.time() logger.info('h {d}'.format(d=t2-t)) t=t2 for lock in locks: lock.release() time.sleep(5)logging.basicConfig(level=logging.DEBUG, format='[%(asctime)s %(threadName)s] %(message)s', datefmt='%H:%M:%S')locks=[]N=5for n in range(N): lock=threading.Lock() locks.append(lock) t=threading.Thread(target=f,args=(lock,n)) t.start()threading.Thread(target=h,args=(locks,)).start()
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)