LDD操作延迟(延缓)

延迟:

     一,内核定时器

             1,内核定时器用在延迟指定时长之后调度异步函数执行(调度异步函数在延迟指定时长之后执行);

             2,内核定时器在 “软件中断”上下文中,以院子模式运行,所以就会有众多限制:

1》不能访问用户空间,由于在软件中断上下文中,所以没有与用户空间进程相关的进程资源,所以无法访问用户空间;

                        2》在原子模式下current指针失效,

                        3》定时器异步函数中不能休眠与调度,由于在软件中断上下文中运行,所以禁止休眠,也不能使用信号量,因为信号量可能引起休眠,只能使用自旋锁(spinlock_t),原子变量(atomic_t) 机制

           

需要注意的问题:由于定时器函数异步执行,必然会带来资源的竞态访问问题,所以定时器函数访问的数据结构必须针对并发访问进行控制;

                                   措施:使用自旋锁(spinlock_t),原子变量(atomic_t);

             3,linux内核定时器的实现:

                      头文件:<linux/timer.h>

                     数据结构:struct timer_list{... , unsigned long expires,void(*function)(unsigned long),unsigned long data};

                     操作:         初始化:DEFINE_TIMER(timer,expires,function,data);//编译时静态初始化;

                                                          void init_timer(struct timer_list *);//运行时动态初始化;

                                              添加:void add_timer(struct timer_list *);

                                              移除:void del_timer(struct timer_list *);

     二,tasklet

            tasklet 和内核定时器运行原理一样,都是在"软件中断"上下文中以原子模式运行,所以限制条件也一样,但是没有定时器的时间限制,所以就没有定时器对时间的要求精确;

            数据结构:struct tasklet_struct {... , void (*func)(unsigned long),unsigned long};

                   操作:初始化:DECLARE_TASKLET(tasklet,func,data);//静态初始化;

                                               DECLARE_TASKLET_DISABLED(tasklet,func,data);//静态初始化为不能被调度的tasklet;

                                               tasklet_init(struct tasklet_struct *,void (*func)(unsigned long),unsigned long);//运行时动态初始化;


                           调度执行:schedule_tasklet(struct tasklet_struct *);

                                              schedule_hi_tasklet(struct tasklet_struct *);//高优先级调度;

                           

                    设置不可调度:tasklet_disable(struct tasklet_struct *);

                        启用tasklet:tasklet_enable(struct tasklet_struct *);


                                    撤销:tasklet:tasklet_kill(struct tasklet_struct *);

     三,workqueue:

                        1,workqueue运行在特殊的内核进程中,所以workqueue不必以原子模式运行;

                              和tasklet的主要区别有两点:

                                   1,tasklet运行在“软件中断”上下文中,必须快速在短时间内执行完毕,不能休眠和调度,必须以原子模式运行;

                                   2,workqueue运行在特殊的内核进程中,所以可以延时一定时长再执行,可以休眠,不必以原子模式运行;

                        

                       两者都不能访问用户空间;


                     2,数据结构:

                           struct workqueue {};

                           struct work_struct{...,void (*func)(unsigned long),unsigned long};

                          

                          操作:创建队列:struct workqueue create_workqueue(void);

              

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值