脚本的惩罚不断在后台循环

时间:2009-04-23 14:08:25

标签: python resources performance queue

我知道discussed中的这个主题已经past,但我对资源使用情况有点偏执。

我正在研究编写一个用于排队作业的守护进程,以便将文件存档到我正在处理的Web应用程序的zip文件中。它会表现得像这样:

while True:
    while morejobs():
        zipfile()
    sleep(15seconds)

在后台循环播放的进程会消耗什么样的资源(假设没有拉链)?有什么我应该知道或小心的吗?

编辑:

看起来大多数答案都关注睡眠的持续时间。我盲目地将它设置为睡眠(在代码示例中),每次15毫秒。我实际上打算这是15秒,我已经“更新”了代码以反映这一点。

再次编辑:

脚本睡眠的最短合理时间是多少?是5秒到低?我不知道这个应用程序的负载是什么,或者新的作业被添加到队列的频率。

8 个答案:

答案 0 :(得分:4)

睡眠不会产生任何开销。 Linux操作系统使用一个非常简单的信号唤醒休眠过程。

你所展示的是“忙碌等待”的设计模式。

为了消除开销,你只想在有工作要做的时候被唤醒。

如何做到这一点。

  1. 等待阅读。

  2. 等待选择函数调用。请参阅http://docs.python.org/library/select.html

  3. 等待锁定被释放。请参阅http://docs.python.org/library/posixfile.html

  4. 其中,等待阅读也许是最简单的。从管道或插座读取是你想要做的。

    我猜你有一个“多作者 - 单读者”设计模式。在这种情况下,有两种候选解决方案。

    1. 每个插槽多个请求。这是类似FTP的解决方案,您可以编写一个简单的服务器来侦听一个套接字上的连接,并为每个客户端打开一个专用连接。然后使用select来确定哪个客户端正在发送文件。

    2. 每个插槽的单个请求。这是类似HTTP的解决方案,您在某个套接字中接收请求,并且请求是大量数据。请求全部完成后,套接字将关闭,以便其他客户端可以获取它。

    3. 在这两种情况下,您没有睡觉 - 您正在等待I / O完成。

答案 1 :(得分:1)

最好在新文件到达时重新启动作业,而不是在15秒内休眠。

  • 处理可用文件
  • 每隔60秒或您选择的任何时间间隔检查新文件
  • 当新文件到达时,处理它以及自上一个间隔以来可能已到达的任何其他文件

答案 2 :(得分:1)

为什么不使用cron作业每分钟运行一次脚本?至少你不依赖自己的循环来在后台持续运行。

答案 3 :(得分:1)

如果需要(并且这些数字是示例)文件到达时间为20秒,处理文件需要5秒,那么您的进程中甚至会在检测到该情况之前等待另外7.5秒造成的伤害是多少文件在那里?

休眠过程对CPU的影响应该尽可能接近零。

所以不,我根本不会关心这方面。

您应该关注的一件事是如果失败,如何自动重启过程。我会每隔5分钟(你选择的实际频率)运行一个cron作业来杀掉旧副本(礼貌地,只有当它正在运行时),然后开始一个新的。这样,如果出现问题,最多只能有5分钟的停机时间。

我礼貌地说,因为旧版本可能正在处理文件,你不应该打断它,除非它是可以恢复的。

答案 4 :(得分:1)

作为替代方案,您可以降低流程的优先级。 (我只熟悉windows方法)

在Windows上:

def setpriority(pid=None,priority=1):
    """ Set The Priority of a Windows Process.  Priority is a value between 0-5 where
        2 is normal priority.  Default sets the priority of the current
        python process but can take any valid process ID. """

    import win32api,win32process,win32con

    priorityclasses = [win32process.IDLE_PRIORITY_CLASS,
                       win32process.BELOW_NORMAL_PRIORITY_CLASS,
                       win32process.NORMAL_PRIORITY_CLASS,
                       win32process.ABOVE_NORMAL_PRIORITY_CLASS,
                       win32process.HIGH_PRIORITY_CLASS,
                       win32process.REALTIME_PRIORITY_CLASS]
    if pid == None:
        pid = win32api.GetCurrentProcessId()
    handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid)
    win32process.SetPriorityClass(handle, priorityclasses[priority])

自: http://code.activestate.com/recipes/496767/

答案 5 :(得分:0)

即使没有什么可以处理的,这也有可能打击你的CPU。

编辑:实际上sleep()将参数视为秒数,而不是毫秒,因此我认为CPU不会成为问题。不过,也许您可​​以使用cron作业安排这样的事情。

答案 6 :(得分:0)

除了锤击你的cpu的成本之外,还有 morejobs()调用的成本。您可以通过为 sleep()使用更高的值来缓解,或者您可以使用某种接收请求的邮箱,然后触发 zipfile()操作。

某些操作通常会安排后台线程暂时检查某些内容。在这种情况下,最好使用 sleep()的合理值。

答案 7 :(得分:0)

“一千个合理的观点值得一次衡量”。

试试吧。