Source code for cup.util.thread

#!/usr/bin/python
# -*- coding: utf-8 -*
# #############################################################################
#
#  Copyright (c) 2014 Baidu.com,  Inc. All Rights Reserved
#
# #############################################################################
"""
:author:
    Zhaominghao Guannan Ma
:create_date:
    2014
:last_date:
    2014
:descrition:
    cup thread module
"""

__all__ = ['async_raise', 'CupThread', 'RWLock']


import threading
import time
import ctypes

import cup


[docs]def async_raise(tid, exctype): """Raises an exception in the threads with id tid""" return ctypes.pythonapi.PyThreadState_SetAsyncExc( tid, ctypes.py_object(exctype) )
[docs]class CupThread(threading.Thread): """ CupThread继承threading.Thread, 支持threading.Thread所有功能和特性, CupThread扩展了三个功能,raise_exc给线程发送raise信号,get_my_tid返回线程id, terminate同步中止线程 """
[docs] def get_my_tid(self): """ 返回线程id """ if not self.isAlive(): cup.log.warn('the thread is not active') return None # do we have it cached? if hasattr(self, '_thread_id'): # pylint: disable=E0203 return self._thread_id # pylint: disable=W0212 # no, look for it in the _active dict for tid, tobj in threading._active.items(): if tobj is self: # pylint: disable=W0201 self._thread_id = tid return tid
[docs] def raise_exc(self, exctype): """ 异步给线程发送raise,发送成功返回1,线程已经停止返回0,其他错误返回!=1 :param exctype: raise Exception, exctype type is class """ return async_raise(self.get_my_tid(), exctype)
[docs] def terminate(self, times=15): """ 异步raise线程,尝试中止线程 中止成功返回True, 线程已经停止返回True, 停止失败返回False。 (在返回True的时候,表示线程已经被中止, 在中止失败的过程中,会重试times次) """ cnt = 0 while self.isAlive(): self.raise_exc(cup.err.ThreadTermException) time.sleep(1) cnt += 1 if cnt > times: return False return True
[docs]class RWLock(object): """ 读写锁类 """ def __init__(self): self._lock = threading.Lock() self._cond = threading.Condition(self._lock) self._rd_num = 0 self._wt_num = 0
[docs] def acquire_writelock(self, wait_time=None): """ 获取写锁, 如果wait_time赋值且!=None的数,会等待wait_time. 如果之后还没拿到锁, 将raise RuntimeError """ self._cond.acquire() if self._wt_num > 0 or self._rd_num > 0: try: self._cond.wait(wait_time) except RuntimeError as error: raise RuntimeError(str(error)) self._wt_num += 1 self._cond.release()
[docs] def release_writelock(self): """ 释放写锁 """ self._cond.acquire() self._wt_num -= 1 if self._wt_num == 0: self._cond.notify_all() self._cond.release()
[docs] def acquire_readlock(self, wait_time=None): """ 获取读锁, 如果wait_time赋值且!=None的数,会等待wait_time. 如果之后还没拿到锁, 将raise RuntimeError """ self._cond.acquire() if self._wt_num > 0: try: self._cond.wait(wait_time) except RuntimeError as error: raise RuntimeError(error) self._rd_num += 1 self._cond.release()
[docs] def release_readlock(self): """ 释放读锁 """ self._cond.acquire() self._rd_num -= 1 if self._rd_num == 0 and self._wt_num == 0: self._cond.notify() self._cond.release() # vi:set tw=0 ts=4 sw=4 nowrap fdm=indent