同步操作将从 OpenHarmony-SIG/python 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
"""A generally useful event scheduler class.Each instance of this class manages its own queue.No multi-threading is implied; you are supposed to hack thatyourself, or use a single instance per application.Each instance is parametrized with two functions, one that issupposed to return the current time, one that is supposed toimplement a delay. You can implement real-time scheduling bysubstituting time and sleep from built-in module time, or you canimplement simulated time by writing your own functions. This canalso be used to integrate scheduling with STDWIN events; the delayfunction is allowed to modify the queue. Time can be expressed asintegers or floating point numbers, as long as it is consistent.Events are specified by tuples (time, priority, action, argument, kwargs).As in UNIX, lower priority numbers mean higher priority; in thisway the queue can be maintained as a priority queue. Execution of theevent means calling the action function, passing it the argumentsequence in "argument" (remember that in Python, multiple functionarguments are be packed in a sequence) and keyword parameters in "kwargs".The action function may be an instance method so ithas another way to reference private data (besides global variables)."""import timeimport heapqfrom collections import namedtupleimport threadingfrom time import monotonic as _time__all__ = ["scheduler"]class Event(namedtuple('Event', 'time, priority, action, argument, kwargs')):__slots__ = []def __eq__(s, o): return (s.time, s.priority) == (o.time, o.priority)def __lt__(s, o): return (s.time, s.priority) < (o.time, o.priority)def __le__(s, o): return (s.time, s.priority) <= (o.time, o.priority)def __gt__(s, o): return (s.time, s.priority) > (o.time, o.priority)def __ge__(s, o): return (s.time, s.priority) >= (o.time, o.priority)Event.time.__doc__ = ('''Numeric type compatible with the return value of thetimefunc function passed to the constructor.''')Event.priority.__doc__ = ('''Events scheduled for the same time will be executedin the order of their priority.''')Event.action.__doc__ = ('''Executing the event means executingaction(*argument, **kwargs)''')Event.argument.__doc__ = ('''argument is a sequence holding the positionalarguments for the action.''')Event.kwargs.__doc__ = ('''kwargs is a dictionary holding the keywordarguments for the action.''')_sentinel = object()class scheduler:def __init__(self, timefunc=_time, delayfunc=time.sleep):"""Initialize a new instance, passing the time and delayfunctions"""self._queue = []self._lock = threading.RLock()self.timefunc = timefuncself.delayfunc = delayfuncdef enterabs(self, time, priority, action, argument=(), kwargs=_sentinel):"""Enter a new event in the queue at an absolute time.Returns an ID for the event which can be used to remove it,if necessary."""if kwargs is _sentinel:kwargs = {}event = Event(time, priority, action, argument, kwargs)with self._lock:heapq.heappush(self._queue, event)return event # The IDdef enter(self, delay, priority, action, argument=(), kwargs=_sentinel):"""A variant that specifies the time as a relative time.This is actually the more commonly used interface."""time = self.timefunc() + delayreturn self.enterabs(time, priority, action, argument, kwargs)def cancel(self, event):"""Remove an event from the queue.This must be presented the ID as returned by enter().If the event is not in the queue, this raises ValueError."""with self._lock:self._queue.remove(event)heapq.heapify(self._queue)def empty(self):"""Check whether the queue is empty."""with self._lock:return not self._queuedef run(self, blocking=True):"""Execute events until the queue is empty.If blocking is False executes the scheduled events due toexpire soonest (if any) and then return the deadline of thenext scheduled call in the scheduler.When there is a positive delay until the first event, thedelay function is called and the event is left in the queue;otherwise, the event is removed from the queue and executed(its action function is called, passing it the argument). Ifthe delay function returns prematurely, it is simplyrestarted.It is legal for both the delay function and the actionfunction to modify the queue or to raise an exception;exceptions are not caught but the scheduler's state remainswell-defined so run() may be called again.A questionable hack is added to allow other threads to run:just after an event is executed, a delay of 0 is executed, toavoid monopolizing the CPU when other threads are alsorunnable."""# localize variable access to minimize overhead# and to improve thread safetylock = self._lockq = self._queuedelayfunc = self.delayfunctimefunc = self.timefuncpop = heapq.heappopwhile True:with lock:if not q:breaktime, priority, action, argument, kwargs = q[0]now = timefunc()if time > now:delay = Trueelse:delay = Falsepop(q)if delay:if not blocking:return time - nowdelayfunc(time - now)else:action(*argument, **kwargs)delayfunc(0) # Let other threads run@propertydef queue(self):"""An ordered list of upcoming events.Events are named tuples with fields for:time, priority, action, arguments, kwargs"""# Use heapq to sort the queue rather than using 'sorted(self._queue)'.# With heapq, two events scheduled at the same time will show in# the actual order they would be retrieved.with self._lock:events = self._queue[:]return list(map(heapq.heappop, [events]*len(events)))
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。