深入Linux C/C++ Timer定时器的实现核心原理

本文详细介绍了Linux下实现定时器的各种方法,包括最小堆、时间轮以及timerfd。讨论了不同实现的优缺点,如时间轮的高效性和timerfd的精确性。还探讨了如何在C/C++中封装定时器,如何选择最佳的定时器容器,以及如何处理文件描述符资源的限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我曾以为像定时器这样基础的功能,操作系统会有一个完备的实现。当需要开启一个定时任务的时候,会有一个优雅的、如下形式的接口:

typedef void (*callback)(void*);
void setTimeout(unsigned int second,callback cb,void* arg);

可是事与愿违,Linux下不存在这样的接口。
文章相关视频讲解:

如何实现分布式定时器及核心原理:如何实现分布式定时器及核心原理

详解Linux网络编程相关的细节处理:详解Linux网络编程相关的细节处理

C/C++ Linux服务器开发高级架构学习视频点击:C/C++Linux服务器开发/Linux后台架构师-学习视频

定时器的实现原理

定时器的实现依赖的是CPU时钟中断,时钟中断的精度就决定定时器精度的极限。一个时钟中断源如何实现多个定时器呢?对于内核,简单来说就是用特定的数据结构管理众多的定时器,在时钟中断处理中判断哪些定时器超时,然后执行超时处理动作。而用户空间程序不直接感知CPU时钟中断,通过感知内核的信号、IO事件、调度,间接依赖时钟中断。用软件来实现动态定时器常用数据结构有:时间轮、最小堆和红黑树。下面就是一些知名的实现:

Hierarchy 时间轮算法:Linux内核

红黑树最小堆算法:Asio C++ Library或nginx 

 

Linux上的定时函数

要想使用上面那样的定时器功能,我们必须利用Linux上现有的定时通知函数,封装一个定时器。Linux上的定时通知函数五花八门,要封装我们自己的定时器,首先需要选用一个定时通知的函数。查阅资料整理出了Linux上所有的定时函数,如下表:

Function

Type

Precision

Remark

sleep(3)

unsigned int

second

 

usleep(3)

useconds_t

microsecond

 

nanosleep(2)

struct timespec

nanosecond

 

clock_nanosleep(2)

struct timespec

nanosecond

It differs in allowing the caller to select the clock against which the sleep interval is to be measured, and in allowingthe sleep interval to be specified as either an absolute or a relative value.

alarm(2)

unsigned int

second

SIGALRM

setitimer(2)

struct itimerval

microsecond

SIGALRM

timer_settime(2)

struct itimerspec

nanosecond

notify method : struct sigevent

Timerfd API

File descriptor

nanosecond

From linux kernel 2.6.25

前四个函数比较鸡肋,会让调用线程挂起,原地等待定时器超时,否定。

alarm()和setitimer(),它们的通知机制采用了信号SIGALRM,由于SIGALRM信号不可靠,会造成超时通知不可靠,而且多线程中处理信号也是一个麻烦事,也不考虑。

timer_create()/timer_settime()系列函数是POSIX规定,精度达到纳秒级,提供了一个数据结构struct sigevent可以指定一个实时信号作为通知信号,同时也可以设置线程ID,将信号传递到指定的线程。相比前两个函数,有了不小的改进,可以作为一个备选的实现,但是可以预见到封装起来不会很轻松。此外使用此系列的函数,需要链接librt库。

事实上,我们遗漏掉了几个同样具有定时的功

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值