Linux C 中的定时器库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12463554/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 14:22:29  来源:igfitidea点击:

Timer library in C

clinuxmultithreading

提问by m4n07

I'm looking for an open source timer library written in C. The library should have Timer callback functions, etc.

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

On searching I see POSIX timersor setitimer(), which use a signal based approach that may lead to problems in multithreaded code.

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

Say if I use POSIX Timers inside threaded code, the signals won't be reaching to the correct place. If I use several timers in a process then each one should use different signals. Are there any other alternatives?

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

采纳答案by Chimera

Since you are running Linux, I would recommend using the built in POSIX timer API's.

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

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

Here is a link to some documentationshowing how to use POSIX timers which provide support for callback functions.

这是一些文档的链接,该链接展示了如何使用为回调函数提供支持的 POSIX 计时器。

Regarding multiple timers in a process, the documentation says this:

关于一个进程中的多个计时器,文档是这样说的:

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

Note that POSIX timers can be used in a threaded application by setting up notification using SIGEV_THREAD_ID as shown below:

请注意,通过使用 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.

回答by tsturzl

This is far to simple to create a library for.

为之创建库非常简单。

example:

例子:

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

回答by cmeerw

The Linux way of doing it would be via timerfd_createwhich integrates nicely with epoll-based event loops (and thereby avoiding the restrictions of signal handlers)

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