Linux定时器

这篇具有很好参考价值的文章主要介绍了Linux定时器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. Linux定时器的概念:

Linux定时器是一种软件机制,用于在指定的时间间隔或特定时间点执行特定的任务。它是基于内核的机制,可以用于各种应用场景,如定时任务调度、延时处理、周期性事件触发等。

运作机制(工作原理):Linux定时器的工作原理主要分为两个部分:定时器的创建和定时器的触发。

  1. 定时器的创建:创建定时器的步骤包括:

    • 定义定时器结构体
    • 初始化定时器结构体
    • 设置定时器超时时间
    • 注册定时器回调函数。

    通过这些步骤,将定时器添加到内核的定时器列表中。

  2. 定时器的触发:当定时器超时时间到达时,内核会触发定时器,执行注册的回调函数。回调函数可以是用户指定的函数,用于执行特定的任务。

数据结构:Linux定时器的数据结构主要有以下几种:

  1. 定时器结构体(struct timer_list):用于定义定时器的属性,如超时时间、回调函数等。

  2. 内核定时器列表:内核维护了一个定时器列表,用于存储所有的定时器。通过链表等数据结构将定时器连接起来,方便管理和触发。

优点:

  • 精确性:Linux定时器可以实现高精度的定时任务调度,满足实时性要求。
  • 灵活性:可以根据需求设置不同的定时器超时时间和回调函数,适用于各种场景。
  • 可扩展性:内核提供了丰富的定时器接口,可以根据需要进行扩展和定制。

缺点:

  • 内核资源占用:每个定时器都需要占用一定的内核资源,如果创建过多的定时器可能会占用过多的内存和CPU资源。
  • 系统开销:定时器的触发和回调函数的执行会带来一定的系统开销,可能会影响系统性能。

应用场景:Linux定时器广泛应用于以下场景:

  • 定时任务调度:如定时执行某个任务、定时发送数据等。
  • 延时处理:如延时关闭设备、延时释放资源等。
  • 周期性事件触发:如定时采集数据、定时更新状态等。

二. 其他相关的概念和机制:

  1. POSIX定时器:POSIX定时器是一种与Linux定时器类似的机制,提供了更高级的接口和功能,可以实现更复杂的定时任务调度。

  2. 内核定时器API:Linux内核提供了一系列的定时器API,如timer_create、timer_settime、timer_gettime等,用于创建和操作定时器。

  3. 定时器分辨率:定时器分辨率是指定时器的最小时间单位,决定了定时器的精度。在Linux中,定时器分辨率一般为10ms。

三. 更多的应用场景:

  1. 网络应用:定时器可以用于实现网络超时重传、心跳检测等功能。

  2. 嵌入式系统:定时器可以用于实现周期性任务,如定时采集传感器数据、定时更新显示等。

  3. 多媒体应用:定时器可以用于实现音视频播放、动画效果等的定时控制。

四.用户空间的定时器 和 Linux内核中的定时器

用户空间的定时器和 Linux 内核中的定时器是两个不同的概念,它们的区别如下:

  1. 位置不同

    • 用户空间的定时器是在应用程序中使用的定时器,由用户空间的程序来设置和管理。
    • Linux 内核中的定时器是在操作系统内核中使用的定时器,由内核来设置和管理。
  2. 权限不同

    • 用户空间的定时器受限于应用程序的权限,只能在用户空间中进行操作。
    • Linux 内核中的定时器由内核进行管理,不受应用程序权限的限制。
  3. 实现方式不同

    • 用户空间的定时器通常是通过使用系统调用(如 setitimer()timer_settime())或库函数(如 sleep()usleep())来实现的。
    • Linux 内核中的定时器是通过内核中的定时器机制来实现的,如内核定时器 API、定时器中断等。
  4. 精度不同

    • 用户空间的定时器的精度受限于应用程序所运行的环境和系统的时钟频率。
    • Linux 内核中的定时器的精度通常较高,可以达到纳秒级别。
  5. 用途不同

    • 用户空间的定时器常用于应用程序中的任务调度、定时操作、超时处理等。
    • Linux 内核中的定时器常用于内核中的任务调度、定时器中断、延迟处理等。

选择使用哪个定时器函数取决于具体的需求和使用场景。以下是一些考虑因素:

  1. 功能需求:根据需要选择适合的功能。

    • 如果只需要在定时器到期时发送信号,可以使用 setitimer() 函数。
    • 如果需要在定时器到期时执行特定的回调函数,可以使用 timer_settime() 函数。
    • 如果需要在内核中初始化和管理定时器,可以使用 init_timer() 函数。
  2. 精度要求:不同的定时器函数可能具有不同的精度。如果需要较高的精度,可以考虑使用 Linux 内核中的定时器函数。

  3. 编程环境:根据所使用的编程环境和语言,选择相应的定时器函数。

    • 例如,setitimer()timer_settime() 是用户空间的函数,适用于大多数编程语言。
    • init_timer() 是在内核中使用的函数,需要在内核模块或驱动程序中使用。
  4. 可移植性:一些定时器函数可能在不同的操作系统或平台上具有不同的行为或支持程度。如果需要编写可移植的代码,需要考虑函数的可移植性。

总的来说,这两者都是 Linux 系统中的函数,选择使用哪个定时器函数应该根据具体需求和使用场景进行评估。

对于大多数应用程序来说,timer_settime() 函数是一个较新且功能强大的选择,可以在定时器到期时执行回调函数。但在某些特定的场景下,可能需要使用其他定时器函数来满足需求。

总结:

  • 用户空间的定时器和 Linux 内核中的定时器是两个不同的概念,用途和实现方式都有所不同,这两者都是 Linux 系统中的函数。
  • 用户空间的定时器由应用程序管理,受限于应用程序的权限和环境;
  • 而 Linux 内核中的定时器由内核管理,具有较高的精度和更广泛的用途。
  • 用户空间的定时器函数(如 setitimer()timer_settime()sleep()usleep())是通过系统调用或库函数提供的,用于在用户空间中设置和管理定时器。
  • Linux 内核中的定时器函数(如 init_timer()、定时器中断处理函数)是在内核中实现的,用于在内核中设置和管理定时器。
  • 这些函数都是 Linux 系统提供的定时器相关的函数。

五. Linux定时器常用的系统调用c函数

函数名 功能 参数 返回值
timer_create() 创建一个新的定时器 clockid_t clockid:时钟标识符
struct sigevent *sevp:定时器超时时的通知方式
timer_t *timerid:返回的定时器标识符
int:成功返回0,失败返回错误码
timer_settime() 设置定时器的超时时间和回调函数 timer_t timerid:定时器标识符
int flags:定时器行为标志
const struct itimerspec *new_value:新的超时时间和回调函数
struct itimerspec *old_value:旧的超时时间和回调函数
int:成功返回0,失败返回错误码
timer_gettime() 获取定时器的当前超时时间和剩余时间 timer_t timerid:定时器标识符
struct itimerspec *curr_value:当前超时时间和剩余时间
int:成功返回0,失败返回错误码
timer_delete() 删除一个已创建的定时器 timer_t timerid:定时器标识符 int:成功返回0,失败返回错误码
timer_getoverrun() 获取定时器超时次数 timer_t timerid:定时器标识符 int:成功返回超时次数,失败返回错误码
timer_settime64() 设置定时器的超时时间和回调函数(支持 64 位的超时时间) timer_t timerid:定时器标识符
int flags:定时器行为标志
const struct __kernel_itimerspec64 *new_value:新的超时时间和回调函数
struct __kernel_itimerspec64 *old_value:旧的超时时间和回调函数
int:成功返回0,失败返回错误码
timer_gettime64() 获取定时器的当前超时时间和剩余时间(支持 64 位的超时时间) timer_t timerid:定时器标识符
struct __kernel_itimerspec64 *curr_value:当前超时时间和剩余时间
int:成功返回0,失败返回错误码
timerfd_create() 创建一个新的定时器文件描述符 int clockid:时钟标识符
int flags:定时器行为标志
int:成功返回定时器文件描述符,失败返回错误码
timerfd_settime() 设置定时器文件描述符的超时时间和回调函数 int fd:定时器文件描述符
int flags:定时器行为标志
const struct itimerspec *new_value:新的超时时间和回调函数
struct itimerspec *old_value:旧的超时时间和回调函数
int:成功返回0,失败返回错误码
timerfd_gettime() 获取定时器文件描述符的当前超时时间和剩余时间 int fd:定时器文件描述符
struct itimerspec *curr_value:当前超时时间和剩余时间
int:成功返回0,失败返回错误码
clock_gettime() 获取指定时钟的当前时间 clockid_t clock_id:时钟标识符
struct timespec *tp:当前时间
int:成功返回0,失败返回错误码
clock_settime() 设置指定时钟的时间 clockid_t clock_id:时钟标识符
const struct timespec *tp:新的时间
int:成功返回0,失败返回错误码
clock_getres() 获取指定时钟的分辨率 clockid_t clock_id:时钟标识符
struct timespec *res:分辨率
int:成功返回0,失败返回错误码
nanosleep() 使当前进程休眠指定的时间 const struct timespec *req:休眠时间
struct timespec *rem:剩余的休眠时间
int:成功返回0,失败返回剩余的休眠时间
usleep() 使当前进程休眠指定的微秒数 unsigned int usec:休眠的微秒数 int:成功返回0,失败返回错误码
------------------ ------------------------------------------------------------ ------------------------------------------------------------ ------------------------------------------------------------
alarm() 设置一个定时器,在指定的时间间隔后发送 SIGALRM 信号给当前进程 unsigned int seconds:定时器的时间间隔 unsigned int:成功返回剩余的定时器时间,失败返回错误码
setitimer() 设置定时器的超时时间和回调函数 int which:定时器类型
const struct itimerval *new_value:新的超时时间和回调函数
struct itimerval *old_value:旧的超时时间和回调函数
int:成功返回0,失败返回错误码
getitimer() 获取定时器的当前超时时间和剩余时间 int which:定时器类型
struct itimerval *curr_value:当前超时时间和剩余时间
int:成功返回0,失败返回错误码
signal() 设置一个函数来处理信号,即带有 sig 参数的信号处理程序 int signum:信号编号
void (*handler)(int):信号处理函数
void (*handler)(int):之前设置的信号处理函数

以上是一些常用的 Linux 定时器相关的 C 函数,这些函数可以用于设置和管理定时器,获取定时器的超时时间和剩余时间,创建定时器文件描述符等。具体的使用方法和参数细节可以参考相关函数的文档和示例代码。
表格中还包括了 alarm()setitimer()getitimer()signal()这几个函数。
这几个函数也可以用于设置和管理定时器,获取定时器的超时时间和剩余时间,但是它们的使用方式和参数与表格中的其它函数有所不同。具体的使用方法和参数细节可以参考相关函数的文档和示例代码。

六. Linux定时器常用的内核中的C函数

函数名 功能 参数
hrtimer_init() 初始化一个高精度定时器 struct hrtimer *timer - 定时器对象
clockid_t clock_id - 时钟 ID
enum hrtimer_mode mode - 定时器模式
hrtimer_start() 启动一个高精度定时器 struct hrtimer *timer - 定时器对象
ktime_t time - 定时器到期的时间
const enum hrtimer_mode mode - 定时器模式
hrtimer_cancel() 取消一个高精度定时器 struct hrtimer *timer - 定时器对象
hrtimer_forward() 将一个高精度定时器向前调整指定的时间 struct hrtimer *timer - 定时器对象
ktime_t now - 当前时间
ktime_t interval - 调整的时间间隔
hrtimer_get_remaining() 获取一个高精度定时器的剩余时间 struct hrtimer *timer - 定时器对象
ktime_t *remaining - 剩余时间
hrtimer_set_expires() 设置一个高精度定时器的到期时间 struct hrtimer *timer - 定时器对象
ktime_t time - 到期时间
hrtimer_active() 检查一个高精度定时器是否处于活动状态 struct hrtimer *timer - 定时器对象
hrtimer_init_sleeper() 初始化一个高精度定时器睡眠器 struct hrtimer_sleeper *sl - 睡眠器对象
hrtimer_start_range_ns() 启动一个高精度定时器,并指定到期时间的范围 struct hrtimer *timer - 定时器对象
ktime_t time - 定时器到期的时间
u64 delta_ns - 到期时间的范围
hrtimer_cancel() 取消一个高精度定时器 struct hrtimer *timer - 定时器对象
hrtimer_forward() 将一个高精度定时器向前调整指定的时间 struct hrtimer *timer - 定时器对象
ktime_t now - 当前时间
ktime_t interval - 调整的时间间隔
hrtimer_get_remaining() 获取一个高精度定时器的剩余时间 struct hrtimer *timer - 定时器对象
ktime_t *remaining - 剩余时间
hrtimer_set_expires_range_ns() 设置一个高精度定时器的到期时间的范围 struct hrtimer *timer - 定时器对象
ktime_t time - 到期时间
u64 delta_ns - 到期时间的范围
hrtimer_active() 检查一个高精度定时器是否处于活动状态 struct hrtimer *timer - 定时器对象

七. 示例代码:使用 Linux定时器

1.使用 alarm() 设置定时器并处理信号

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

// 信号处理函数
void signal_handler(int signum)
{
    printf("Received SIGALRM signal\n");
    // 处理定时器到期的操作
}

int main()
{
    // 注册信号处理函数
    signal(SIGALRM, signal_handler);

    // 设置定时器,5秒后发送SIGALRM信号
    alarm(5);

    // 等待信号到达
    pause();

    return 0;
}

2.使用 setitimer() 设置定时器并处理定时器到期事件

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>

// 定时器到期时的回调函数
void timer_callback(int signum)
{
    printf("Timer expired!\n");
    // 处理定时器到期的操作
}

int main()
{
    struct itimerval timer;

    // 注册定时器到期的信号处理函数
    signal(SIGALRM, timer_callback);

    // 设置定时器的初始值为2秒,间隔为1秒
    timer.it_value.tv_sec = 2;
    timer.it_value.tv_usec = 0;
    timer.it_interval.tv_sec = 1;
    timer.it_interval.tv_usec = 0;

    // 设置定时器
    if (setitimer(ITIMER_REAL, &timer, NULL) == -1) {
        perror("setitimer");
        exit(EXIT_FAILURE);
    }

    // 等待定时器到期
    sleep(5);

    return 0;
}

3.使用 getitimer() 获取定时器的当前值

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

int main()
{
    struct itimerval timer;

    // 获取定时器的当前值
    if (getitimer(ITIMER_REAL, &timer) == -1) {
        perror("getitimer");
        exit(EXIT_FAILURE);
    }

    // 输出定时器的当前值
    printf("Timer value: %ld seconds %ld microseconds\n", timer.it_value.tv_sec, timer.it_value.tv_usec);
    printf("Timer interval: %ld seconds %ld microseconds\n", timer.it_interval.tv_sec, timer.it_interval.tv_usec);

    return 0;
}

以上示例代码展示了如何使用 alarm()setitimer()getitimer() 函数来创建、设置和使用定时器。
第一个示例使用 alarm() 设置定时器,当定时器到期时,会发送 SIGALRM 信号,并通过注册的信号处理函数进行处理。
第二个示例使用 setitimer() 设置定时器,定时器每隔1秒触发一次,并在到期时调用回调函数进行处理。
第三个示例使用 getitimer() 获取定时器的当前值,并输出定时器的当前值和间隔值。

4.下面的示例代码,演示了如何在内核中使用高精度定时器。

#include <linux/hrtimer.h>
#include <linux/ktime.h>

static struct hrtimer hr_timer;

enum hrtimer_restart timer_callback(struct hrtimer *timer)
{
    // 定时器到期时的处理逻辑
    printk(KERN_INFO "Timer expired!\n");

    // 重新设置定时器的到期时间
    hrtimer_forward_now(timer, ms_to_ktime(1000));

    return HRTIMER_RESTART;
}

int init_module(void)
{
    // 初始化定时器
    hrtimer_init(&hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);

    // 设置定时器的到期时间和回调函数
    hr_timer.function = timer_callback;
    hrtimer_start(&hr_timer, ms_to_ktime(1000), HRTIMER_MODE_REL);

    return 0;
}

void cleanup_module(void)
{
    // 取消定时器
    hrtimer_cancel(&hr_timer);
}

以上示例代码使用了内核中的 hrtimer_init()hrtimer_start() 函数创建和启动了一个高精度定时器。
在定时器到期时,会触发回调函数 timer_callback,并在其中处理定时器到期的逻辑。
在示例代码中,定时器每隔一秒触发一次,并输出 “Timer expired!”。最后,使用 hrtimer_cancel() 函数取消了定时器。

八.其它

setitimer()函数

setitimer 函数是一个系统调用,用于设置定时器。它可以用于在指定的时间间隔内触发信号,并执行相应的信号处理函数。

函数原型如下:

#include <sys/time.h>

int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);

参数说明:

  • which:指定定时器类型,可以是以下值之一:
    • ITIMER_REAL:真实时间定时器,使用系统的真实时间计时。
    • ITIMER_VIRTUAL:虚拟时间定时器,仅在进程执行用户态代码时计时。
    • ITIMER_PROF:虚拟时间和系统时间定时器,包括进程执行用户态代码和内核态代码的时间。
  • new_value:指向 struct itimerval 结构体的指针,用于设置新的定时器值。
    • it_interval:定时器的间隔时间,即定时器触发信号的时间间隔。
    • it_value:定时器的初始值,即第一次触发信号的时间。
  • old_value:指向 struct itimerval 结构体的指针,用于保存旧的定时器值。

返回值:

  • 成功:返回 0。
  • 失败:返回 -1,并设置相应的错误码。

示例用法:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

void timer_handler(int signum)
{
    printf("Timer expired!\n");
}

int main()
{
    struct itimerval timer;
    struct sigaction sa;

    // 安装信号处理函数
    sa.sa_handler = timer_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGALRM, &sa, NULL);

    // 设置定时器
    timer.it_value.tv_sec = 1; // 初始值为 1 秒
    timer.it_value.tv_usec = 0;
    timer.it_interval.tv_sec = 1; // 间隔为 1 秒
    timer.it_interval.tv_usec = 0;
    setitimer(ITIMER_REAL, &timer, NULL);

    // 等待定时器触发
    while (1)
    {
    }

    return 0;
}

以上示例代码演示了如何使用 setitimer 函数设置一个定时器,每隔一秒触发一次 SIGALRM 信号,并执行相应的信号处理函数 timer_handler
—————————————————————————————------———————————————————————

signal() 函数

函数名 signal()
功能 设置信号处理函数
参数 int signum:信号编号
void (*handler)(int):信号处理函数
返回值 void (*handler)(int):之前设置的信号处理函数

功能介绍:
signal() 函数用于设置信号处理函数,用于处理特定信号的到达。当特定信号到达时,系统会调用设置的信号处理函数。该函数可以用于捕获和处理各种信号,例如中断信号、终止信号等。

参数介绍:

  1. int signum:信号编号,表示要设置的信号。
  2. void (*handler)(int):信号处理函数,是一个指向函数的指针,用于处理特定信号的到达。函数的参数是信号编号。

返回值介绍:
void (*handler)(int):之前设置的信号处理函数。如果之前未设置信号处理函数,则返回 SIG_DFL(默认信号处理函数)。

以下是将 Linux 定时器的 signal() 函数的示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>

void timer_handler(int signum) {
    printf("Timer expired.\n");
}

int main() {
    struct sigaction sa;
    struct itimerval timer;

    // 安装信号处理程序
    sa.sa_handler = timer_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGALRM, &sa, NULL);

    // 设置定时器
    timer.it_value.tv_sec = 1;
    timer.it_value.tv_usec = 0;
    timer.it_interval.tv_sec = 1;
    timer.it_interval.tv_usec = 0;
    setitimer(ITIMER_REAL, &timer, NULL);

    // 无限循环,等待定时器信号
    while (1) {
        sleep(1);
    }

    return 0;
}

在上面的代码中,

  • 我们首先定义了一个 timer_handler() 函数,用于处理定时器信号。
  • 然后,在 main() 函数中,我们使用 sigaction() 函数安装信号处理程序,将 timer_handler() 函数与 SIGALRM 信号关联起来。
  • 接着,我们使用 setitimer() 函数设置定时器,使其每隔 1 秒触发一次。最后,我们使用一个无限循环来等待定时器信号。

请注意,上述代码仅为示例,实际使用时可能需要根据具体需求进行适当的修改。
另外,为了保证定时器的准确性,建议在使用 setitimer() 函数之前将 struct itimerval 结构体中的值初始化为 0。

那么signal() 注册的信号捕捉函数 与 setitimer()设置的定时器 是如何绑定的?

  • signal() 函数和 setitimer() 函数之间没有直接的绑定关系。它们分别用于不同的目的,但可以一起使用来实现定时器功能。
  • signal() 函数用于设置信号处理函数,当指定的信号到达时,系统会调用设置的信号处理函数。通过设置合适的信号处理函数,我们可以捕获和处理特定的信号,例如定时器信号。
  • setitimer() 函数用于设置定时器,它可以在指定的时间间隔内周期性地触发一个信号。通过设置定时器,我们可以在定时器信号到达时执行相应的操作。
  • 在实际应用中,我们可以使用 signal() 函数设置一个信号处理函数,然后使用 setitimer() 函数设置一个定时器,使其以一定的时间间隔触发一个信号。当定时器信号到达时,系统会调用设置的信号处理函数。

————————————————————————————————————————————————————

setitimer()、timer_settime()、init_timer()有什么区别

setitimer()timer_settime()init_timer() 是三个不同的函数,用于设置定时器。

  1. setitimer() 函数是一个系统调用,用于设置定时器。它可以用于在指定的时间间隔内触发信号,并执行相应的信号处理函数。setitimer() 函数的原型如下:

    #include <sys/time.h>
    
    int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
    
    • setitimer() 函数的参数 new_value 用于设置新的定时器值,包括定时器的初始值和间隔时间。
    • 它可以设置三种类型的定时器:真实时间定时器、虚拟时间定时器和虚拟时间和系统时间定时器。
  2. timer_settime() 是一个用户空间的函数,用于设置和修改 POSIX 定时器的参数。

    函数原型如下:

    int timer_settime(timer_t timerid, int flags, const struct itimerspec *new_value, struct itimerspec *old_value);
    
    • timer_settime() 函数用于设置定时器的参数,其中包括定时器的间隔时间和初始值。
    • 如果 flags 参数设置为 TIMER_ABSTIME,则 new_value 参数中的时间值被视为绝对时间;
    • 否则,时间值被视为相对时间。
  3. init_timer() 函数是内核中的一个函数,用于初始化一个定时器结构体。它的原型如下:

    void init_timer(struct timer_list *timer);
    
    • init_timer() 函数的参数 timer 是一个指向 timer_list 结构体的指针,用于初始化定时器结构体。
    • 定时器结构体 timer_list 是用于在内核中管理定时器的数据结构,包含定时器的超时时间、回调函数等信息。

它们之间的主要区别如下:

功能不同

  • setitimer() 是一个旧的函数,用于设置定时器的初始值和间隔值,并在定时器到期时发送指定的信号。
  • timer_settime() 是一个新的函数,用于设置定时器的初始值和间隔值,并在定时器到期时执行指定的回调函数。
  • init_timer() 是一个 Linux 内核中的函数,用于初始化一个内核定时器,与用户空间的定时器设置无关。

精度不同

  • setitimer() 使用 struct itimerval 结构来设置定时器的值,其中的时间单位是微秒级别(us)。
  • timer_settime() 使用 struct itimerspec 结构来设置定时器的值,其中的时间单位可以是纳秒级别(ns)。
  • init_timer() 是在内核中初始化一个定时器,精度取决于系统的时钟频率。

信号处理不同

  • setitimer() 在定时器到期时发送指定的信号(如 SIGALRM),需要通过注册信号处理函数来处理定时器到期事件。
  • timer_settime() 在定时器到期时执行指定的回调函数,无需注册信号处理函数。
  • init_timer() 是在内核中初始化一个定时器,不涉及用户空间的信号处理。

使用环境不同

  • setitimer()timer_settime() 是用户空间的函数,用于在应用程序中设置定时器。
  • init_timer() 是 Linux 内核中的函数,用于在内核中初始化定时器。

总结:

    • setitimer() 是一个较旧的系统调用函数,用于在用户空间设置定时器并触发相应的信号。它是一个比较底层的接口,可以精确控制定时器的时间间隔和触发方式。使用 setitimer() 可以实现定时任务、周期性任务等功能。
    • timer_settime() 是一个较新的系统调用函数,用于在用户空间设置定时器并执行回调函数;
    • init_timer() 是内核中的函数,主要用于内核开发中。它用于初始化定时器结构体,并将定时器添加到内核的定时器列表中。在内核开发中,可以使用 init_timer() 创建和管理定时器,然后使用其他函数(如 mod_timer())设置定时器的超时时间和回调函数。
  1. setitimer()timer_settime() 都可以用于在用户空间中设置定时器,但它们的使用方式略有不同。

    • setitimer() 使用 struct itimerval 结构体来设置定时器的初始值和间隔值。它可以设置定时器的绝对时间和相对时间,通过发送指定的信号来触发定时器到期事件。需要注册信号处理函数来处理定时器到期事件。

    • timer_settime() 使用 struct itimerspec 结构体来设置定时器的初始值和间隔值。它可以设置定时器的绝对时间和相对时间,在定时器到期时执行指定的回调函数,无需注册信号处理函数。

  2. init_timer() 是一个内核函数,用于在内核中初始化定时器。它是用于内核开发的函数,与用户空间的定时器设置无关。它需要在内核模块或驱动程序中使用,用于创建和管理内核定时器。

    • 在内核开发中,可以使用 init_timer() 初始化一个定时器结构体,并将其添加到内核的定时器列表中。然后,可以使用其他函数(如 mod_timer())来设置定时器的超时时间和回调函数。

    • init_timer() 函数与 setitimer()timer_settime() 的主要区别在于它是在内核中使用的,而不是在用户空间中。

  3. 选择哪个函数更好取决于具体的需求和开发场景。文章来源地址https://www.toymoban.com/news/detail-769597.html

    • 如果你是在用户空间中开发应用程序,并且只需要设置定时器并触发相应的信号,那么使用 setitimer() 就足够了。
    • 如果你是在内核开发中,需要创建和管理定时器,并进行更底层的操作,那么可以使用 init_timer()
    • 在新的应用程序中,更推荐使用 timer_settime() 函数来设置定时器。

到了这里,关于Linux定时器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【单片机】STM32单片机的各个定时器的定时中断程序,标准库

    高级定时器和普通定时器的区别(https://zhuanlan.zhihu.com/p/557896041): TIM1是高级定时器,使用的时钟总线是RCC_APB2Periph_TIM1,和普通定时器不一样。 timer.c timer.h 调用 timer.c timer.h 调用 timer.c timer.h 调用 timer.c timer.h 调用 timer.c timer.h 调用

    2024年02月11日
    浏览(53)
  • 51单片机(七)定时器

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月07日
    浏览(56)
  • 51单片机——定时器中断

    新版51单片机内部有 3 个16位可编程的定时器/计数器,即定时器 T0,T1,T2 。他们既有 定时 功能又有 计数 功能,我们可以通过配置与它们相关的特殊功能寄存器可以选择启用定时功能或计数功能;其中需要注意的是,这个定时器系统是单片机内部的一个独立的硬件部分,它与

    2023年04月10日
    浏览(44)
  • 51单片机定时器实验(汇编)

    基于AT89C51的定时器实验,汇编语言,分享出来是希望各位能共同学习。附上注释希望能认真研究,若有错误请指出,谢谢。 一、实验目的 掌握单片机定时器的使用方法。 掌握中断的使用方法。 二、实验内容 采用中断方式控制定时器。使得单片机P1.0引脚产生周期为1S的方波

    2024年02月11日
    浏览(59)
  • 51单片机之定时器篇

    首先,学好单片机必须要搞懂定时器,定时器是单片机重要的组成部分之一,总之,学不好定时器,单片机相当于没学,下面就让我介绍如何学好单片机定时器。 学习单片机首先要明白的: 1,51单片机有两组定时器/计数器,既可以定时,又可以计数,总称之定时器 2,单片

    2024年02月11日
    浏览(54)
  • 51单片机 | 定时器中断实验

      这一节介绍51单片机的定时器中断。 STC89C5X 含有 3 个定时器:定时器 0、定时器 1、定时器 2(注意: 51 系列单片机一定有基本的 2 个定时器(定时器 0 和定时器 1),但不全有 3 个中断,需要查看芯片手册,通常我们使用的是基本的 2 个定时器:定时器 0/1)。本节要实现

    2024年02月06日
    浏览(111)
  • 51单片机PWM(定时器)

    目录 前言 一、PWM的介绍 二、在定时器中配置PWM 三、代码  总结         PWM普遍应用于惯性系统,我们知道单片机几乎只能输出“1”和“0”两种状态,即开和关,想要输出模拟量是不太容易实现的,那么怎样才能使单片机输出平滑的线性信号呢?没接触过PWM的小伙伴可能第

    2024年02月09日
    浏览(55)
  • 蓝桥杯单片机学习6——定时器/计数器&定时器实现秒表功能

    上一期我们学习了外部中断的相关内容,现在我接着来学习定时器。 定时器/计数器是一种能够对内部时钟信号或者外部输入信号进行计数,当计数值达到设定要求时,向CPU提出中断请求,从而实现定时或计数功能的外设。定时器的基本工作原理是进行计数。 举个栗子 :你可

    2024年02月04日
    浏览(50)
  • 单片机——交通灯(定时器中断)

    1.基础知识 1.1、中断源 中断源符号 名称 中断引起原因 中断号 /INT0 外部中断0 P3.2引脚低电平或下降沿信号 0 T0 定时器0中断 定时,计数器0计数回0溢出 1 /INT01 外部中断1 P3.3引脚低电平或下降沿信号 2 T1 定时器1中断 定时/计数器1计数回0溢出 3 TI/RI 串行口中断 串行通信完成一帧

    2024年02月08日
    浏览(48)
  • 51单片机定时器基础知识

    经验总结:定时器0工作方式1的溢出中断初始值计算 1.晶振11.0592M 11.0592MHz除12为921600Hz,就是一秒921600次机器周期,50ms=46080次机器周期。 65536-46080=19456(4c00) TH0=0x4c,TL0=0x00 2.晶振12M 12MHz除12为1MHz,也就是说一秒=1000000次机器周期。50ms=50000次 机器周期。 65536-50000=15536(3cb0) TH0=0x

    2024年02月04日
    浏览(115)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包