这是我的第一个线程程序。我在这里面临一个奇怪的问题。我正在Django中构建一个类似于应用程序的简单调度程序,其中函数名(将定期执行)及其下一次执行时间将存储在Django Model中。
执行管理命令以启动一个连续运行的线程,以检查是否应执行任何功能,如果是,则启动一个新线程来执行该功能。这样,为每个函数创建了单独的线程(至少就是这个主意!)。
class Command(BaseCommand):
def __init__(self):
super(Command, self).__init__()
self.lock = None
def handle(self, *args, **kwargs):
self.lock = threading.RLock()
t1 = threading.Thread(target=self.cron_thread)
t1.start()
t1.join()
def cron_thread(self):
while True:
# Fetch only Active records
scheduled_actions = Scheduler.objects.filter(active=True)
for scheduled_action in scheduled_actions:
# check if execution is due
if scheduled_action.next_execution_time == datetime.now():
# creating a new thread
function_thread = threading.Thread(target=eval(scheduled_action.function_name), args=[self.lock])
function_thread.start()
function_thread.join()
scheduled_action.next_execution_time = local_timezone.localize(datetime.now() + relativedelta(minutes=scheduled_action.interval))
scheduled_action.run_now = False
scheduled_action.save()
def somefunction(self):
self.lock.acquire()
# function body
self.lock.release()
我创建的用于开始执行整个程序的命令是: python3 manage.py runcrons-debit
执行此命令后,立即在 htop 结果中看到两个进程正在运行,并且消耗了将近80%的CPU,如下图所示:
View Image
请注意,此处尚未调度程序记录处于活动状态。
使调度程序记录处于活动状态并且该函数实际运行时, htop 中显示的进程增加到3,CPU使用率急剧下降到0.0%。如下图所示:
View Image
这里有两件事我听不懂,
答案 0 :(得分:3)
cron_thread
有一个无限循环。此循环首先检索计划的操作,然后循环执行它们。对于每个动作,如果将动作安排在确切的当前时间,则会执行该动作。
如果未安排任何动作,则循环将重复不断地检索计划的动作。如果有动作,它将检查现在是否是执行该动作的时间。这是另一个问题:datetime.datetime.now()
的精度很高(最近的微秒),因此它与动作的预定时间相匹配的可能性很小。这意味着您的循环将检索所有计划的动作,循环所有动作,然后返回顶部。
如果计划的操作时间与当前时间不匹配,则将执行该操作,然后将内部循环移至下一个操作。当它遍历所有动作时,它将回到顶部并再次检索所有动作。
基本上,您的程序会不断将所有计划的操作与当前时间进行比较。这需要处理能力。执行这些动作的更好方法是检查每个新动作的时间,将其添加到任务列表中,计算出需要执行该动作之前所需的延迟,然后设置一个计时器以在必要时执行该动作。延迟(time.sleep
在线程中,after
在tkinter
中调用,这种事情)。