2012-09-17 29 views
9

Busco una biblioteca temporizador de código abierto escrito en C. La biblioteca debe tener funciones de devolución de llamada de temporizador, etc.biblioteca temporizador en C

en la búsqueda veo temporizadores POSIX o setitimer(), que utilizan un enfoque basado en señal que puede conducir a problemas en el código multiproceso.

Digamos que si uso temporizadores POSIX dentro del código roscado, las señales no llegarán al lugar correcto. Si uso varios temporizadores en un proceso, entonces cada uno debería usar diferentes señales. ¿Hay otras alternativas?

+0

Por lo general es útil para explicar por qué esto está siendo votado/cerrado. –

+0

¿Lo buscó? –

+0

Esto está recibiendo votos cercanos porque es probable que solicite debate, argumentos, encuestas o discusiones extensas. Investiga un poco, intenta usar uno o más candidatos, pregúntale si tienes problemas con ellos. O pregunte, por ejemplo, _puedo usar el setitimer de POSIX en el código multiproceso_ ... esa es una buena pregunta – Useless

Respuesta

10

Dado que está ejecutando Linux, le recomendaría usar las API del temporizador POSIX incorporado.

int timer_create(clockid_t clockid, struct sigevent *sevp, timer_t *timerid); 

Aquí hay un enlace a alguna documentation que muestra cómo utilizar temporizadores POSIX que proporcionan soporte para las funciones de devolución de llamada.

En cuanto a varios temporizadores en un proceso, la documentación dice esto:

A program may create multiple interval timers using timer_create(). 

    Timers are not inherited by the child of a fork(2), and are disarmed and 
    deleted during an execve(2). 

    The kernel preallocates a "queued real-time signal" for each timer created 
    using timer_create(). Consequently, the number of timers is limited by the 
    RLIMIT_SIGPENDING resource limit (see setrlimit(2)). 

debe comprender que el POSIX se pueden utilizar en una aplicación roscada mediante la creación de notificación mediante SIGEV_THREAD_ID como se muestra a continuación:

The sevp.sigev_notify field can have the following values: 

     SIGEV_NONE 
       Don't asynchronously notify when the timer expires. Progress of the 
       timer can be monitored using timer_gettime(2). 

     SIGEV_SIGNAL 
       Upon timer expiration, generate the signal sigev_signo for the process. 
       See sigevent(7) for general details. The si_code field of the 
       siginfo_t structure will be set to SI_TIMER. At any point in time, at 
       most one signal is queued to the process for a given timer; see 
       timer_getoverrun(2) for more details. 

     SIGEV_THREAD 
       Upon timer expiration, invoke sigev_notify_function as if it were the 
       start function of a new thread. See sigevent(7) for details. 

     SIGEV_THREAD_ID (Linux-specific) 
       As for SIGEV_SIGNAL, but the signal is targeted at the thread whose ID 
       is given in sigev_notify_thread_id, which must be a thread in the same 
       process as the caller. The sigev_notify_thread_id field specifies a 
       kernel thread ID, that is, the value returned by clone(2) or gettid(2). 
       This flag is only intended for use by threading libraries. 
+0

Si utilizo temporizadores POSIX dentro de un código enhebrado, las señales no llegarán al lugar correcto. Si uso varios temporizadores en un proceso, entonces cada uno debería usar señales diferentes. ¿Alguna otra alternativa? – m4n07

+0

Puede configurar la notificación para que sea compatible con los subprocesos mediante SIGEV_THREAD_ID. Entonces, la señal del temporizador irá a la identificación del hilo al que desea ir. – Chimera

+0

"' Aquí hay un enlace a alguna documentación que muestra cómo usar los temporizadores POSIX que proporcionan soporte para funciones de devolución de llamada "" - ¿dónde? No puedo ver ninguna mención de las funciones de devolución de llamada – Mawg

-6

Esto es muy fácil de crear una biblioteca.

ejemplo:

#include <time.h> 
int main() 
{ 
    time_t start,end; 
    double dif; 
    double duration=40f; //duration of timer 
    bool loop=true; 
    while(loop==true) 
    { 
     time(&start); 
     if(dif==duration) 
     { 
      /*callback*/ 
      dif=0; 
     } 
     //do stuff 
     time(&end); 
     dif+=difftime(end,start); 
    } 
{ 

+0

Solución simple, pero en realidad no proporciona un mecanismo de devolución de llamada adecuado. – Chimera

+0

No sería difícil hacerlo así. Estaba lanzando la idea por ahí. – tsturzl

+3

¡El objetivo de utilizar una devolución de llamada con temporizador es evitar el tiempo en cada iteración!-1 – Thomas

7

La forma en Linux de hacerlo sería a través de timerfd_create la que se integra muy bien con bucles de eventos basados ​​en epoll (y evitando así las restricciones de los gestores de señales)

+0

Me gustaría saber la precisión de resolución del timefd. – m4n07

+0

Es exactamente lo mismo que timer_create ya que la infraestructura subyacente es la misma; solo la interfaz de notificación es diferente. – cmeerw

+0

¡Gracias! Esto es exactamente lo que necesitaba usar con epoll_wait(), sin embargo, creo que pasé una hora investigando temporizadores y epoll sin darme cuenta de esto mencionado por nadie más. Muy agradecido. –