6-定时器_锁_互斥体_自旋锁_原子操作

内核定时器编程:
时钟脉冲:它是soc的重要指标和性能参数。供内核使用(进程调度,计时)。也称为时钟中断,通常是操作系统的0号中断。

jiffies:
  • 内核中表示自系统开机以来,一共发生了多少次时钟脉冲。
HZ:
  • 内核中表示一秒钟发生多少次时钟脉冲
Tick:
  • 内核中表示两次时钟脉冲之间的时间间隔。

内核中在软件层面。提供了一系列数据结构和函数供于底层驱动计时编程。
步骤:
  • 1.定义:
    • struct timer_list xxx;
  • 2.初始化:
    • init_timer(&xxx);
    • xxx.function = do_my_xxx;
    • xxx.data = (unsigned long)ooo;
    • xxx.expeirs = jiffies + 400;
  • 3.使用:

    • 3.1注册并启动定时器:
      • add_timer(&xxx);
    • 3.2完成定时器回调函数:
      void do_my_xxx(unsigned long data)
              {
                  .......
              }
  • 3.3修改定时器延时时间并启动:

    • mod_timer(&xxx,jiffies + 延时时间);
  • 3.4注销定时器:
    • del_timer(&xxx);
并发控制:
  • 多个进程并发访问临界资源区,是会引起竞态现象,由此我们必须对这种现象加以控制,就是并发控制。并发控制中常用的手段
    就是锁。
linux内核中提供的锁:
  • 1.中断屏蔽(强烈推荐不使用)
  • 2.原子操作 (建议不使用,常见于汇编,一般也只是极短的赋值语句)
  • 3.自旋锁
    • 3.1 读写锁 读读进程并发,读写进程互斥,写写进程互斥
    • 3.2 顺序锁 读读进程并发,读写进程并发,写写进程互斥
    • 3.3 RCU 读读进程并发,读写进程并发,写写进程并发
  • 4.信号量 操作pv信号的一种锁,其使用场景和互斥体类似,但效率比互斥体低,故逐渐被互斥体所替代
  • 5.互斥体
自旋锁和互斥体使用的3大原则:
  • 1.当临界资源区较小时,使用自旋锁,当临界资源区比较大时,使用互斥体。因为自旋锁所面临的是自旋等待的cpu资源消耗,
    而互斥体是进程切换的资源消耗。
  • 2.当临界资源区中有引起睡眠的函数时,只能使用互斥体。因为互斥体运行于进程上下文。而自旋锁运行于中断上下文,在中断
    上下文,绝对避免进程调度,否则可能将引起系统崩溃。
  • 3.当临界资源区中有中断时,只能使用自旋锁,而不能使用互斥体。因为互斥体是运行于进程上下文。在中断中会禁止进程调度,
    使用互斥体,将会造成上下文丢失。
1.原子操作:
  • 1.定义并初始化
    • atomic_t xxx = ATOMIC_INIT(1);
  • 2.使用:
    • atomic_dec_and_test(&xxx);
    • atomic_inc(&xxx);
    • 或者:
    • atomic_inc_and_test(&xxx);
    • atomic_dec(&xxx);
  • 2.自旋锁:
    • 1.定义:
      • spinlock_t xxx;
    • 2.初始化:
      • spin_lock_init(&xxx);
    • 3.使用:
      • 3.1上锁:
        • spin_lock(&xxx);
      • 3.2解锁:
        • spin_unlock(&xxx);
    • 3.信号量:
      • 1.定义:
        • struct semaphore xxx;
    • 2.初始化:
      • sema_init(&xxx,1);
    • 3.使用:
      • 3.1上锁:
        • down(&xxx);
      • 3.2解锁:
        • up(&xxx);
  • 4.互斥体:
    • 1.定义:
      • struct mutex xxx;
    • 2.初始化:
      • mutex_init(&xxx);
    • 3.使用:
      • 3.1上锁:
        • mutex_lock(&xxx);
      • 3.2解锁:
        • mutex_unlock(&xxx);

你可能感兴趣的:(驱动)