def _is_owner(self): is_owner = self._owner == _current_thread().name # if is_owner: # self._debug("{0} is the owner", _current_thread().name) # else: # self._debug("{1} is NOT the owner", _current_thread().name) return is_owner
def _do_lock(self, timeout=None): if self._has_owner(): raise RuntimeError("Try to lock when not yet released") self._owner = _current_thread().name self._when = _datetime.now() self.expiration_time = timeout self._info("{0} has take the lock (expiration time {1})", self.owner, self.expiration_time)
def _process_async_queue(): t = _current_thread() t.alive = True while t.alive: function, args, kwargs = _task_queue.get() if function: function(*args, **kwargs) if _log.isEnabledFor(_DEBUG): _log.debug("stopped")
def access(self): """ Request if the give thread is allowed to access the resource. """ # self._debug("%s access()" % _current_thread().name) if not self.isLock(): self._debug("There is no owner of the lock, {0} can pass", _current_thread().name) return True elif self._isOwner(): self._when = _datetime.now() self._debug( "The owner is who is asking ({0}), " "renew its booking", _current_thread().name) return True else: return False
def __popRequester(self): found, pos = self.__searchRequester() if found or pos is not None: self.__pauseRequesterStack.pop(pos) processName = _current_process().name threadName = _current_thread().name self.debug("Removed '%d'th requester" % (pos)) return True self.debug("pop unsatisfied") return False
def __procedure(self): """Function of the fork process""" _current_process().name = "Process%d" % (self.__id) _current_thread().name = "Worker%d" % (self.__id) self.debug("Fork build") while not self.__events.waitStart(self.checkPeriod): self.debug("Waiting start...") try: self.info("Fork starts %s after the event trigger" % (_datetime.now()-self.__events.whenStarted())) except Exception as e: self.warning("Start event received but not propagated when " "it was triggered") while not self._endProcedure(): try: if self.__events.isPaused(): self.info("paused") if self._procedureHas2End(): break while not self.__events.waitResume(self.checkPeriod): pass self.info("resume") else: self.__currentArgin = self.__input.get() self.debug("argin: %s" % (self.__currentArgin)) if self.__preHook is not None: self.debug("call preHook") self.__preHook(self.__currentArgin, **self.__preExtraArgs) if self._procedureHas2End(): break t_0 = _datetime.now() self.__currentArgout = self.__target(self.__currentArgin) t_diff = _datetime.now()-t_0 t_diff = t_diff.total_seconds() self.__computationTime.value += t_diff self.debug("argout: %s (%f seconds)" % (self.__currentArgout, t_diff)) self.__ctr.value += 1 self.__output.put([self.__currentArgin, self.__currentArgout]) if self.__postHook is not None: self.debug("call postHook") self.__postHook(self.__currentArgin, self.__currentArgout, **self.__postExtraArgs) self.__events.step() except Exception as e: self.error("exception: %s" % (e)) _print_exc() # process has finish, lets wake up the monitor self.__internalEvent.set() self.debug("Internal event emitted to report end of the procedure")
def release(self): """ Only the owner can release the lock. """ # self._debug("%s release()" % _current_thread().name) if self._isOwner(): self._debug("{0} releases the lock", self._owner) self._doRelease() return True else: self._error("{0} is NOT allowed to release {1}'s lock", _current_thread().name, self._owner) return False
def request(self, timeout=None): """ Request to book the access. If its free (or has expired a previous one) do it, else reject (even if the owner recalls it). """ # self._debug("%s request()" % _current_thread().name) if not self._has_owner() or self._has_expired(): self._doLock(timeout) return True else: self._warning("{0} request the lock when already is", _current_thread().name) return False
def __thread(self): """Monitor thread function.""" _current_thread().name = "Monitor%d" % (self.__id) self.__prepared.set() self.info("Creating the fork") self.__worker = _Process(target=self.__procedure) while not self.__events.waitStart(self.__checkPeriod): self.debug("Waiting to start") # FIXME: msg to be removed, together with the timeout self.info("Starting the fork") self.__worker.start() self.__processMonitoring() self.info("Monitor has finished its task")
def __new__(cls, callback=None): """Create a weak reference to the current thread. Arguments: callback (optional): Function (or other callable) to call once the current thread stops running. """ try: anchor = _threadlocal.anchor except AttributeError: anchor = _threadlocal.anchor = _Object() anchor._thread = _current_thread() return super().__new__(cls, anchor, callback)
def print_info(msg, level=0, lock=None, top=False, bottom=False): if lock is None: print("{}{}".format("\t" * level, msg)) else: with lock: tab = "\t" * level msg = "Thread {}: {}".format(_current_thread().name, msg) if top or bottom: if top: msg = "{}{}\n{}{}".format(tab, "-" * len(msg), tab, msg) elif bottom: msg = "{}{}}\n{}{}\n".format(tab, msg, tab, "-" * len(msg)) else: msg = "{}{}".format(tab, msg) print(msg)
def __searchRequester(self): nonBookRequest = None processName = _current_process().name threadName = _current_thread().name for i, request in enumerate(self.__pauseRequesterStack): if request[0] == processName and request[1] == threadName: self.debug("Found (%s, %s) as requester in position %d" % (processName, threadName, i)) return (True, i) elif nonBookRequest is None and request[2] is False: nonBookRequest = i self.debug("NOT found (%s, %s) as requester" % (processName, threadName)) if nonBookRequest is not None: self.debug("But a nonBook request found from (%s, %s)" % (self.__pauseRequesterStack[nonBookRequest][0], self.__pauseRequesterStack[nonBookRequest][1])) return (False, nonBookRequest)
def __init__(*args, **kwargs): """Initialize the finalizer. Arguments: function: Function (or other callable) to call once the current thread stops running. *args: Positional arguments for the function. **kwargs: Keyword arguments for the function. """ def __init__(self, function, *args): return self, function, args self, function, args = __init__(*args) try: anchor = _threadlocal.anchor except AttributeError: anchor = _threadlocal.anchor = _Object() anchor._thread = _current_thread() super(finalize, self).__init__(anchor, function, *args, **kwargs)
def __poolMonitorThread(self): _current_thread().name = "PoolMonitor" while not self.__events.waitStart(self.checkPeriod): self.debug("Collector prepared, but processing not started") # FIXME: msg to be removed, together with the timeout while not self.__events.isStopped(): if self.__events.waitStep(self.checkPeriod): self.__events.stepClean() self.debug("STEP event received") self.__collectOutputs() else: self.debug("Periodic check") self.__reviewWorkers() self.__loadAverage.review() self.__memoryPercent.review() while self.activeWorkers > 0: self.debug("Waiting workers to finish") self.__reviewWorkers() if self.activeWorkers > 0: _sleep(self.checkPeriod) self.debug("Pool complete, exiting")
class finalize(_finalize): """Finalizer for the current thread. Unlike normal finalizers, this detects when the current thread stops running, not when a given object is stops being alive. """ __slots__ = () def __init__(self, function, /, *args, **kwargs): """Initialize the finalizer. Arguments: function: Function (or other callable) to call once the current thread stops running. *args: Positional arguments for the function. **kwargs: Keyword arguments for the function. """ try: anchor = _threadlocal.anchor except AttributeError: anchor = _threadlocal.anchor = _Object() anchor._thread = _current_thread() super().__init__(anchor, function, *args, **kwargs)
def __storeRequester(self, book): processName = _current_process().name threadName = _current_thread().name self.__pauseRequesterStack.append([processName, threadName, book]) self.debug("Stored (%s, %s) as a requester (book=%s)" % (processName, threadName, book))
def interrupt(self): self._stream.close() # Wait only a second for thread to terminate. if self.isAlive() and self != _current_thread(): self.join(1.0)
def _threadId(self): return _current_thread().getName()