linxu 应用层sleep函数陷入到内核以及内核msleep函数

文章详细解析了Linux应用层程序如何通过nanosleep和msleep函数进行睡眠,以及这两个函数在内核中的实现过程。nanosleep涉及高精度定时器和主动调度,而msleep则设置任务为不可中断睡眠状态,并通过定时器超时唤醒。同时,文章指出msleep_interruptible允许被信号中断。

Linux应用层程序中调用sleep函数 

使用strace跟踪如下:
strace sleep_test(该main程序中进行sleep(10)调用)

nanosleep({tv_sec=10, tv_nsec=0}, 0x7fec466ca0) = 0
write(1, "sleep test", 10sleep test)              = 10
write(1, "\n", 1
 

  nanosleep最终会陷入到内核/kernel/time/hrtimer.c中

 nanosleep

   ---hrtimer_nanosleep

        ---hrtimer_init_sleeper_on_stack

           ---do_nanosleep

                ---hrtimer_init_sleeper

                   ---freezable_schedule

                       ----__set_current_state(TASK_RUNNING)

do_nanosleep函数是睡眠的核心实现:首先设置任务的状态为可中断的睡眠状态,然后开启了之前设置的高精度定时器,随即调用freezable_schedule进行真正的睡眠

可以看到最终调用主调度器__schedule进行主动调度。

当任务睡眠完成,定时器超时,会调用之前hrtimer_init_sleeper设置的超时回调函数hrtimer_wakeup将睡眠的任务唤醒。hrtimer_wakeup函数如下:

freezable_schedule
->schedule()
    ->__schedule(false); 在kernel/sched/core.c中

处于用户态的任务,如果想要睡眠一段时间必须向内核请求服务(如调用nanosleep系统调用),内核中会设置一个高精度定时器,然后设置任务状态为可中断的睡眠状态,紧接着发生主动调度,这样任务就发生睡眠。

linux内核msleep函数

函数定义在kernel/time/timer.c中:

schedule_timeout_uninterruptible中这里可以看到,首先设置为不可中断状态__set_current_state(TASK_UNINTERRUPTIBLE);  //设置任务状态为不可中断睡眠,然后记录定时器到期要唤醒的任务并通过schedule主动调度。

 msleep不能用于中断上下文,因为中断函数不能休眠。

msleep实现睡眠是通过定时器,首先设置当前任务状态为不可中断睡眠,然后设置定时器超时时间为传递的ms级延迟转换的jiffies,超时回调函数为process_timeout,然后将定时器添加到系统中,最后调用schedule发起主动调度,当定时器超时的时候调用process_timeout来唤醒睡眠的任务。有关process_timeout是使用try_to_wake_up函数如何唤醒一个进程,有待后续继续研究。

        类似msleep可中断的函数为msleep_interruptible,调用时可以被信号唤醒,并返回初始请求睡眠周期中剩余的毫秒数,;一般用于等待队列并需要打断休眠唤醒进程时。

/**
 * msleep_interruptible - sleep waiting for signals
 * @msecs: Time in milliseconds to sleep for
 */
unsigned long msleep_interruptible(unsigned int msecs)
{
    unsigned long timeout = msecs_to_jiffies(msecs) + 1;

    while (timeout && !signal_pending(current))
        timeout = schedule_timeout_interruptible(timeout);
    return jiffies_to_msecs(timeout);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

a2591748032-随心所记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值