我正在寻找一个用 C 编写的开源计时器库。该库应该具有 Timer 回调函数等。
在搜索时,我看到POSIX 计时器或setitimer(),它们使用基于信号的方法,这可能会导致多线程代码出现问题。
假设我在线程代码中使用 POSIX 计时器,信号将不会到达正确的位置。如果我在一个进程中使用多个计时器,那么每个计时器都应该使用不同的信号。还有其他选择吗?
我正在寻找一个用 C 编写的开源计时器库。该库应该具有 Timer 回调函数等。
在搜索时,我看到POSIX 计时器或setitimer(),它们使用基于信号的方法,这可能会导致多线程代码出现问题。
假设我在线程代码中使用 POSIX 计时器,信号将不会到达正确的位置。如果我在一个进程中使用多个计时器,那么每个计时器都应该使用不同的信号。还有其他选择吗?
由于您运行的是 Linux,我建议您使用内置的 POSIX 计时器 API。
int timer_create(clockid_t clockid, struct sigevent *sevp, timer_t *timerid);
这是一些文档的链接,展示了如何使用为回调函数提供支持的 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.
Linux 的做法是通过timerfd_create与基于 epoll 的事件循环很好地集成(从而避免信号处理程序的限制)
为其创建库非常简单。
例子:
#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);
}
{