cron
“现代”守护进程如何在内部安排他们的工作?有些crond
s 过去常常通过at
. 因此,在写出 crontab 后,会crond
:
- 解析所有未来事件的 crontab 和间隔的睡眠?
- 每分钟轮询一次聚合的 crontab 数据库以确定当前时间是否与计划模式匹配?
- 其他?
谢谢,
在这个问题中听到了一些蟋蟀。带有一些离散事件模拟论文和维基百科的优秀'ol RTFC:
http://en.wikipedia.org/wiki/Cron#Multi-user_capability
这个 cron 使用的算法如下:
- 启动时,在所有帐户持有人的主目录中查找名为 .crontab 的文件。
- 对于找到的每个 crontab 文件,确定下一次运行每个命令的时间。
- 将这些命令及其相应时间和“五场”时间说明符放在 Franta-Maly 事件列表中。
- 进入主循环:
- 检查队列头部的任务条目,计算将来要运行多长时间。
- 睡那段时间。
- 在唤醒并验证正确时间后,使用创建它的用户的权限执行队列头部的任务(在后台)。
- 确定未来下次运行该命令的时间,并将其放回当时的事件列表中
我写了一篇博客文章来描述它。
从那里引用相关文本:
PriorityBlockingQueue
优先级为的(线程安全堆)中提取所有任务来执行所有任务job.nextExecutionTime()
。void goToSleep(job, jobQueue){
jobQueue.push(job);
sleep(job.nextExecutionTime() - getCurrentTime());
}
void executeJob(job, jobQueue){
threadpool.submit(job); // async call
if (job.isRecurring()) {
job = job.copy().setNextExecutionTime(getCurrentTime() + job.getRecurringInterval());
jobQueue.add(job);
}
}
@Override
void run(){
while(true)
{
job = jobQueue.pop()
if(job.nextExecutionTime() > getCurrentTime()){
// Nothing to do
goToSleep(job, jobQueue)
}
else{
executeJob(job, jobQueue)
}
}
}
@Override
void run()
{
while(true)
{
newJob = getNewJobFromCrontabFile() // blocking call
jobQueue.push(newJob)
}
}
@Override
void run()
{
while(true)
{
newJob = getNewJobFromCrontabFile() // blocking call
jobQueue.push(newJob)
if(newJob == jobQueue.peek())
{
// The new job is the one that will be scheduled next.
// So wakeup consumer thread so that it does not oversleep.
consumerThread.interrupt()
}
}
}
请注意,这可能不是 cron 在内部实现的方式。但是,这是我能想到的最优化的解决方案。它不需要轮询,所有线程都会休眠,直到它们需要做任何工作。