C中的计时器库

时间:2012-09-17 16:35:01

标签: c linux multithreading

我正在寻找用C编写的开源计时器库。该库应具有Timer回调函数等。

在搜索时,我看到 POSIX计时器 setitimer(),它们使用基于信号的方法,可能会导致多线程代码出现问题。

假设我在线程代码中使用POSIX定时器,信号将无法到达正确的位置。如果我在一个过程中使用多个定时器,那么每个定时器应该使用不同的信号。还有其他选择吗?

3 个答案:

答案 0 :(得分:10)

由于您运行Linux,我建议使用内置的POSIX计时器API。

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

这是指向某些documentation的链接,显示了如何使用POSIX计时器来支持回调函数。

关于流程中的多个计时器,文档说明了这一点:

   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)).

请注意,通过使用SIGEV_THREAD_ID设置通知,可以在线程应用程序中使用POSIX计时器,如下所示:

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.

答案 1 :(得分:7)

Linux的做法是通过timerfd_create,它可以很好地与基于epoll的事件循环集成(从而避免信号处理程序的限制)

答案 2 :(得分:-6)

为。\ n创建库非常简单。

例如:

#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);
    }
{

#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); } {