es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo interrumpo sleep()

Entonces, tengo un bucle while(1) con un sleep(60) segundos al final. El problema es que mi programa puede recibir una instrucción en ese tiempo, pero tendrá que esperar los 60 segundos hasta que se ejecute. He intentado con un handler y mi otro programa enviando una señal (con kill(daemonid, SIGCONT)), pero no parece interrumpir sleep() (es decir, hacer que regrese).

void handler(){
  write(1, "bonjour", 7);
  alarm(1);
}

/<em>bloques de código irrelevantes para la pregunta</em>/

int main(){
/<em>lee y abre archivos</em>/
  struct sigaction execaction;
  memset(&execaction, 0, sizeof(struct sigaction));
  execaction.sa_handler = handler;
  sigaction(SIGCONT, &execaction, NULL);

while(1){
    pf[0].fd = request_pipe;
    pf[0].events = POLLIN;

<pre><code>int p = poll(pf, 1, timeout);

if(pf[0].revents &;amp; POLLIN){

  read(request_pipe, &operation, sizeof(uint16_t));

  switch (operation){
    case CLIENT_REQUEST_CREATE_TASK:
        printf("create\n");
        reply_pipe = open(path2, O_WRONLY);
        rep = SERVER_REPLY_OK;
        write(reply_pipe, &rep, sizeof(int));
        taskid = htobe64(0);
        write(reply_pipe, &taskid, sizeof(uint64_t));
        close(reply_pipe);
        break;
    case CLIENT_REQUEST_LIST_TASKS:
        printf("list\n");
        reply_pipe = open(path2, O_WRONLY);
        rep = SERVER_REPLY_OK;
        write(reply_pipe, &rep, sizeof(int));
        close(reply_pipe);
        break;
    default:
        printf(":(");
  }
}else{
  printf("Tiempo agotado\n");
  printf("coucou \n");
}
  close(request_pipe);
  int t = 60;
  sleep(t);
</code></pre>

}
  return 0;
}
}

Entonces, el programa que escribe en estos tubos, al final de cada opción envía una señal de kill a este proceso demonio. Sé que escribe las cosas correctamente porque después de un minuto se ejecuta.

Entonces, ¿cómo puedo detener sleep() en este caso si recibo algo en el tubo para leer (y luego reiniciarlo al final del bucle)? He intentado con SIGCONT, pero no parece estar funcionando.

Tags:  ,

Answer

  1. Avatar for davy.ai

    La función sleep() bloquea el hilo llamador durante un número especificado de segundos. En este caso, el hilo principal se bloquea durante 60 segundos, incluso si se recibe una instrucción en el mientras tanto. Esto se puede evitar implementando un mecanismo para interrumpir la espera y ejecutar la instrucción.

    Una solución es utilizar la función alarm() en combinación con un manejador de señales. El manejador de señales, en este caso, SIGALRM, se llama una vez que la alarma ha expirado. Por lo tanto, en lugar de llamar sleep(60), establezca la alarma durante 60 segundos utilizando alarm(60) y permita que el manejador de señales interrumpa la alarma y realice la operación.

    Para manejar la instrucción recibida, modifique la llamada a poll() para establecer un tiempo de espera más corto que refleje el tiempo real restante hasta que expire la siguiente alarma. Por ejemplo, si la alarma está configurada durante 60 segundos y han transcurrido 10 segundos desde la última alarma, establezca el tiempo de espera en 50 segundos (timeout = 50000).

    Modifique la función handler() para incluir el código para manejar la instrucción recibida. Esta función se llamará cuando expire la alarma o cuando se reciba la señal SIGCONT.

    void handler(){
      alarm(0); // detener la alarma actual
      read(request_pipe, &operation, sizeof(uint16_t)); // manejar la instrucción
      // realizar la instrucción aquí
      alarm(60); // reiniciar la alarma durante 60 segundos
    }
    

    Finalmente, agregue una verificación en el bucle principal para ver si hay alguna instrucción pendiente antes de llamar a poll(). Si se encuentra una instrucción, llame a la función handler() para manejarla de inmediato.

    if (poll(pf, 1, 0) > 0) {
      handler();
    } else {
      printf("Tiempo de espera finalizado\n");
    }
    

    Con este enfoque, la función sleep() nunca se llama y el hilo solo se bloquea cuando espera una entrada. La alarma se utiliza para asegurarse de que el hilo se despierte regularmente y verifique si hay instrucciones pendientes. El manejador de señales maneja cualquier instrucción pendiente antes de reiniciar la alarma durante otros 60 segundos.

Comments are closed.