File size: 2,688 Bytes
d1e2d14 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | import sys
import os
import errno
import ctypes
import struct
import threading
from .future import Future
from .timerfd import *
class Thread(Future):
def __init__(self, target = None, name = None, args = (), kwargs = None):
super().__init__()
self.__target = target
self.__args = args
self.__kwargs = {} if kwargs is None else kwargs
self.__thread = threading.Thread(target=self.__ThreadFunc, name=name, daemon=True)
def Start(self):
return self.__thread.start()
def GetId(self):
return self.__thread.ident
def GetNativeId(self):
return self.__thread.native_id
def __ThreadFunc(self):
value = None
try:
value = self.__target(*self.__args, **self.__kwargs)
self.Ready(value)
except:
info = sys.exc_info()
self.Fail(f"[Thread] target func raise exception: name={info[0].__name__}, args={str(info[1].args)}")
class RecurrentThread(Thread):
def __init__(self, interval: float = 1.0, target = None, name = None, args = (), kwargs = None):
self.__quit = False
self.__inter = interval
self.__loopTarget = target
self.__loopArgs = args
self.__loopKwargs = {} if kwargs is None else kwargs
if interval is None or interval <= 0.0:
super().__init__(target=self.__LoopFunc_0, name=name)
else:
super().__init__(target=self.__LoopFunc, name=name)
def Wait(self, timeout: float = None):
self.__quit = True
super().Wait(timeout)
def __LoopFunc(self):
# clock type CLOCK_MONOTONIC = 1
tfd = timerfd_create(1, 0)
spec = itimerspec.from_seconds(self.__inter, self.__inter)
timerfd_settime(tfd, 0, ctypes.byref(spec), None)
while not self.__quit:
try:
self.__loopTarget(*self.__loopArgs, **self.__loopKwargs)
except:
info = sys.exc_info()
print(f"[RecurrentThread] target func raise exception: name={info[0].__name__}, args={str(info[1].args)}")
try:
buf = os.read(tfd, 8)
# print(struct.unpack("Q", buf)[0])
except OSError as e:
if e.errno != errno.EAGAIN:
raise e
os.close(tfd)
def __LoopFunc_0(self):
while not self.__quit:
try:
self.__loopTarget(*self.__args, **self.__kwargs)
except:
info = sys.exc_info()
print(f"[RecurrentThread] target func raise exception: name={info[0].__name__}, args={str(info[1].args)}")
|