我正在考虑编写一个用于排队作业的守护程序,以将文件归档为我正在开发的 Web 应用程序的 zip 文件。它的行为是这样的:
while True:
while morejobs():
zipfile()
sleep(15seconds)
一个在后台不断循环的进程会消耗什么样的资源(假设没有要压缩的东西)?有什么我应该注意或小心的吗?
我正在考虑编写一个用于排队作业的守护程序,以将文件归档为我正在开发的 Web 应用程序的 zip 文件。它的行为是这样的:
while True:
while morejobs():
zipfile()
sleep(15seconds)
一个在后台不断循环的进程会消耗什么样的资源(假设没有要压缩的东西)?有什么我应该注意或小心的吗?
睡眠不涉及开销。Linux 操作系统使用一个非常简单的信号来唤醒一个睡眠进程。
您所展示的是“忙于等待”的设计模式。
为了消除开销,您只想在有工作要做时才被唤醒。
方法来做到这一点。
等着读。
等待选择函数调用。请参阅http://docs.python.org/library/select.html
等待一个锁被释放。请参阅http://docs.python.org/library/posixfile.html。
其中,等待读取可能是最简单的。从管道或套接字读取是您想要做的。
我猜你有一个“多作者单读者”的设计模式。在这种情况下,有两个候选解决方案。
每个套接字多个请求。这是一个类似 FTP 的解决方案,您可以编写一个简单的服务器来侦听一个套接字上的连接并为每个客户端打开一个专用连接。然后您使用 select 来确定哪个客户端正在发送文件。
每个套接字单个请求。这是类似 HTTP 的解决方案,您在某个套接字中接收请求,并且请求是大量数据。当请求全部完成时,套接字将关闭,以便另一个客户端可以获取它。
在这两种情况下,您不是在睡觉——您是在等待 I/O 完成。
与其睡 15 秒,不如有一个回调来在新文件到达时重新开始你的工作。
作为替代方案,您可以降低进程的优先级。(我只熟悉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])
为什么不使用 cron 作业每分钟左右运行一次脚本呢?至少您不依赖自己的循环在后台连续运行。
如果文件到达需要 20 秒(这些数字是示例),而您需要 5 秒来处理它,那么您的进程在检测到文件之前平均再等待 7.5 秒有什么危害?那里?
休眠进程应该对 CPU 的影响尽可能接近于零。
所以不,我根本不会关心这个方面。
您应该关心的一件事是如果进程失败,如何自动重新启动进程。我会每 5 分钟运行一次 cron 作业(您选择的实际频率)以杀死旧副本(礼貌地,并且仅在它正在运行时),然后启动一个新副本。这样,如果出现问题,最多只有 5 分钟的停机时间。
我礼貌地说,因为旧的可能正在处理文件,除非它是可恢复的,否则你不应该中断它。
即使没有要处理的内容,这也可能会影响您的 CPU。
编辑:实际上sleep()
将参数作为秒数,而不是毫秒,所以我认为 CPU 不会成为问题。不过,也许您可以使用 cron 作业来安排这样的事情。
除了敲打 CPU 的成本外,还有morejobs()调用的成本。您可以通过使用更高的sleep()值来缓解,或者您可以使用某种接收请求然后触发zipfile()操作的邮箱。
对于某些操作来说,安排一个后台线程来临时检查某些东西是正常的。在这种情况下,最好的方法是对sleep()使用合理的值。
“一千个有道理的意见值得一次衡量”。
去尝试一下。