为什么空闲的Python线程占用高达90%的CPU?

2024-04-19 08:27:08 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我的第一个线程程序。我现在面临一个奇怪的问题。我正在Django中构建一个简单的类似调度器的应用程序,其中函数名(将定期执行)将与其下一次执行时间一起存储在Django模型中。
执行一个管理命令来启动一个线程,该线程连续运行,以检查是否有任何函数的执行到期,如果是,则启动一个新线程来执行该函数。这样,就为每个函数创建了单独的线程(至少,这是一个想法!)。你知道吗

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管理.pyruncrons借记卡

当我执行这个命令时,我可以在htop结果中看到两个进程正在运行,几乎消耗了80%的CPU,如下图所示: View Image 请注意,这里还没有活动的计划程序记录。

当调度程序记录处于活动状态,并且函数实际运行时,htop中显示的进程将增加到3个,CPU使用率将急剧降低到0.0%。如下图所示: View Image

有两件事我不明白,

  • 一旦函数的执行结束并且没有函数被执行,htop结果返回到两个进程,几乎消耗80-90%的CPU。为什么这里的空闲线程占用这么多CPU?你知道吗
  • 另外,当没有执行任何函数时,为什么仍显示两个进程?我可以理解其中一个是命令本身,但是是什么导致了第二个进程被创建呢? 你知道吗

  • Tags: 函数命令self程序lock进程deffunction
    1条回答
    网友
    1楼 · 发布于 2024-04-19 08:27:08

    cron_thread有一个无限循环。此循环首先检索计划的操作,然后对其进行循环。对于每个操作,如果该操作是在当前时间安排的,则执行该操作。你知道吗

    如果没有计划任何操作,循环将一次又一次地继续检索计划的操作。如果有一个动作,它会检查现在是否是执行它的时候。还有一个问题:datetime.datetime.now()的精度非常高(最接近微秒),因此它与动作的预定时间匹配的可能性非常低。这意味着您的循环将检索所有计划的操作,循环所有操作,然后返回顶部。你知道吗

    如果计划动作的时间与当前时间不匹配,则执行该动作,然后内部循环移动到下一个动作。当它循环执行所有操作时,它将返回到顶部并再次检索所有操作。你知道吗

    基本上,你的行动总是在计划中。这需要处理能力。执行这些操作的更好方法是检查每个新操作添加到任务列表中的时间,计算到需要执行该操作之前的必要延迟,然后设置一个计时器在必要延迟之后执行该操作(在线程中,aftertkinter中调用,诸如此类)。你知道吗

    相关问题 更多 >