GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo programa internamente cron los trabajos?

Unos grillos escuchados en esta pregunta. Buen 'ol RTFC con algunos documentos de simulación de eventos discretos y Wikipedia:

http://en.wikipedia.org/wiki/Cron#Multi-user_capability

El algoritmo utilizado por este cron es el siguiente:

  1. Al iniciar, busque un archivo llamado .crontab en los directorios de inicio de todos los titulares de cuentas.
  2. Para cada archivo crontab encontrado, determine la próxima vez en el futuro que se ejecutará cada comando.
  3. Coloque esos comandos en la lista de eventos de Franta-Maly con su tiempo correspondiente y su especificador de tiempo de "cinco campos".
  4. Ingrese al bucle principal:
    1. Examine la entrada de la tarea al principio de la cola, calcule cuánto tiempo en el futuro debe ejecutarse.
    2. Dormir durante ese período de tiempo.
    3. Al despertar y después de verificar la hora correcta, ejecute la tarea al principio de la cola (en segundo plano) con los privilegios del usuario que la creó.
    4. Determine la próxima vez en el futuro para ejecutar este comando y vuelva a colocarlo en la lista de eventos en ese momento

Escribí una publicación de blog describiéndola.
Citando el texto relevante de allí:

  • Podemos tener un grupo de subprocesos finito que ejecutará todas las tareas tomándolas de un PriorityBlockingQueue (montón seguro para subprocesos) priorizado en job.nextExecutionTime() .
  • Lo que significa que el elemento superior de este montón siempre será el que se disparará antes.
  • Seguiremos el patrón estándar de productor-consumidor de subprocesos.
  • Tendremos un subproceso que se ejecutará en un ciclo infinito y enviará nuevos trabajos al grupo de subprocesos después de consumirlos de la cola. Llamémoslo QueueConsumerThread :
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)
        }
    }
}
  • Habrá un subproceso más que monitoreará el archivo crontab en busca de nuevos trabajos agregados y los empujará a la cola.
  • Llamémoslo QueueProducerThread :
@Override
void run()
{
    while(true)
    {
        newJob = getNewJobFromCrontabFile() // blocking call
        jobQueue.push(newJob)
    }
}
  • Sin embargo, hay un problema con esto:
    • Imagine que Thread1 está durmiendo y se despertará después de una hora.
    • Mientras tanto, llega una nueva tarea que se supone que debe ejecutarse cada minuto.
    • Esta nueva tarea no podrá comenzar a ejecutarse hasta una hora más tarde.
  • Para resolver este problema, podemos hacer que ProducerThread despierte a ConsumerThread de su suspensión con fuerza siempre que la nueva tarea deba ejecutarse antes que la tarea principal en la cola:
@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()
        }
    }
}

Tenga en cuenta que es posible que no sea así como se implementa cron internamente. Sin embargo, esta es la solución más óptima que se me ocurre. No requiere sondeo y todos los subprocesos duermen hasta que necesitan hacer algún trabajo.


Linux
  1. Cómo configurar trabajos cron en cPanel

  2. Cómo usar el formato de trabajo cron para programar tareas en Linux

  3. Cómo configurar un trabajo cron en TrueNAS

  4. Cómo eliminar trabajos cron

  5. Cómo programar trabajos de Cron con Crontab

Trabajos cron programados

¿Cómo verificar la salida de Cron Jobs en Hostinger?

Cómo configurar trabajos cron de cPanel desde WHM

Cómo agregar trabajos cron en cPanel

Cómo usar el comando Jobs en Linux

Cómo programar trabajos con Cron en Linux