首页 > 系统相关 >Linux内核信号量(semaphore)使用与源码分析

Linux内核信号量(semaphore)使用与源码分析

时间:2023-09-21 16:12:58浏览次数:41  
标签:struct waiter Linux list 信号量 源码 semaphore sem

https://blog.csdn.net/Auris/article/details/107404962

一. 在Linux内核驱动中使用信号量(semaphore)常规操作步骤:


[0]. 定义信号量结构体变量;

struct semaphore sem;
 


[1]. 初始化信号量变量

  1.   void sema_init(struct semaphore *sem, int n);
  2.   eg. sema_init(&sem, 1);


[2]. 获取信号量:

  1.   void down(struct semaphore *sem);                    // 获取信号量, 资源不足则睡眠等待
  2.   int down_trylock(struct semaphore* sem);            // 试图获取信号量, 如果没有则直接返回 不睡眠
  3.   int down_interruptible(struct semaphore* sem);        // 获取信号量, 可以被信号打断;


[3]. 释放信号量:

void up(struct semaphore* sem);                        // 释放信号量, 唤醒信号等待队列中的第一个等待进程
 

二. 重要的数据结构体:

  1.   struct semaphore {
  2.       raw_spinlock_t lock;
  3.       unsigned int count;
  4.       struct list_head wait_list;
  5.   };
  6.    
  7.   struct semaphore_waiter {
  8.       struct task_struct *task;
  9.       bool up;
  10.       struct list_head list;
  11.   };

三. down操作源码分析, 以down函数为例:

  1.   void down(struct semaphore *sem)
  2.   {
  3.       unsigned long flags;
  4.       raw_spin_lock_irqsave(&sem->lock, flags);
  5.       if (likely(sem->count > 0))
  6.           sem->count--;
  7.       else
  8.           __down(sem);
  9.       raw_spin_unlock_irqrestore(&sem->lock, flags);
  10.   }
  1.   static noinline void __sched __down(struct semaphore *sem)
  2.   {
  3.       __down_common(sem, TASK_UNINTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
  4.   }
  1.   static inline int __sched __down_common(struct semaphore *sem, long state, long timeout)
  2.   {
  3.       struct task_struct *task = current;
  4.       struct semaphore_waiter waiter;
  5.    
  6.       list_add_tail(&waiter.list, &sem->wait_list);
  7.       waiter.task = task;
  8.       waiter.up = false;
  9.    
  10.       for (;;) {
  11.           if (signal_pending_state(state, task))
  12.               goto interrupted;
  13.           if (unlikely(timeout <= 0))
  14.               goto timed_out;
  15.           __set_task_state(task, state);
  16.           raw_spin_unlock_irq(&sem->lock);
  17.           timeout = schedule_timeout(timeout);
  18.           raw_spin_lock_irq(&sem->lock);
  19.           if (waiter.up)
  20.               return 0;
  21.       }
  22.    
  23.    timed_out:
  24.       list_del(&waiter.list);
  25.       return -ETIME;
  26.    
  27.    interrupted:
  28.       list_del(&waiter.list);
  29.       return -EINTR;
  30.   }

四. up操作源码分析, 以up函数为例:

  1.   void up(struct semaphore *sem)
  2.   {
  3.       unsigned long flags;
  4.       raw_spin_lock_irqsave(&sem->lock, flags);
  5.       if (likely(list_empty(&sem->wait_list)))
  6.           sem->count++;
  7.       else
  8.           __up(sem);
  9.       raw_spin_unlock_irqrestore(&sem->lock, flags);
  10.   }
  1.   static noinline void __sched __up(struct semaphore *sem)
  2.   {
  3.       struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list,
  4.                           struct semaphore_waiter, list);
  5.       list_del(&waiter->list);
  6.       waiter->up = true;
  7.       wake_up_process(waiter->task);
  8.   }

五. 流程分析与注意点:


[0]. sem->count的数值>=0, 如果count>0, 说明当前信号量没有被占用, 可以获取;
     如果count<=0(==0), 需要根据sem->list来添加等待任务或者唤醒任务;

 

标签:struct,waiter,Linux,list,信号量,源码,semaphore,sem
From: https://www.cnblogs.com/tomato-haha/p/17720190.html

相关文章

  • arm linux 移植 ffmpeg 库 + x264 + x265
    背景Ffmpeg中带有h264的解码,没有编码,需要添加x264。libx264是一个自由的H.264编码库,是x264项目的一部分,使用广泛,ffmpeg的H.264实现就是用的libx264。FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转......
  • Linux常用命令2
    cat/proc/mtd查看NandFlash分区情况flash_erase/dev/mtd300nandwrite-s0x60000-p/dev/mtd3/home/root/imx6ull-14x14-nand-7-1024x600-c.dtbsyncflash_erase/dev/mtd400nandwrite-p/dev/mtd4/home/root/zImagesyncps-Akill100 ls/dev/tty* “ttym......
  • Linux系统的物理cpu数、核数、逻辑cpu个数查看
    1#总核数=物理CPU个数X每颗物理CPU的核数2#总逻辑CPU数=物理CPU个数X每颗物理CPU的核数X超线程数34#查看物理CPU个数5cat/proc/cpuinfo|grep"physicalid"|sort|uniq|wc-l67#查看每个物理CPU中core的个数(即核数)8......
  • 基于Java开发的数字化询价招标采购系统(SRM系统源码)
    在如今商业环境中,企业的采购流程变得越来越重要。传统的采购方式可能存在诸多弊端,例如效率低下、信息不透明、易滋生腐败等。为了解决这些问题,许多企业开始转向SRM(供应商关系管理)系统。本文将详细介绍SRM数字询价招标系统,包括其概念、功能和优势。系统展示和获取代码方式在文末。......
  • windows下操作静态库lib(相当于linux下的ar命令)
    linux下有ar可以操作.a文件,windows下提供了lib.exe操作lib文件,从vs的控制台编译环境中可以直接调用。主要有一下几个操作:列出obj::lib/listxxx.lib释放obj:lib/extract:xxx.obj/out:new.objxxx.lib删除obj:lib/remove:xxx.objxxx.lib增加obj:libxxx.objxxx.lib ......
  • 视频直播app源码,VBA 之Interior 对象设置底色
    视频直播app源码,VBA之Interior对象设置底色1.ColorIndex索引颜色值Sub索引颜色值()  Fori=1To56    Cells(i,1).Interior.ColorIndex=i    Cells(i,2)=i  Nexti     Fori=1To56    Cells(i,3).Interior.ColorInd......
  • 为何学linux及用处
    目前企业使用的操作系统无非就是国产类的,windows和linux类。我们要提升自己的技能,需要学习这两款。我记得在大学时期,学习过windows以及linux,但当时觉得又不常用,就学的模棱两可。毕业之后,你会发现,其实这两种操作系统是很主流的。为什么学?下面就是一些工作中遇到的例子分享一下。我......
  • linux的ps功能简介
    环境centos7.9简介ps是Linux系统中一个非常有用的命令,用于显示当前系统中正在运行的进程信息。它提供了许多功能,可以帮助用户监控和管理系统中的进程功能作用显示进程列表:Ps命令可以显示当前系统中所有正在运行的进程的列表。默认情况下,它会显示与当前终端相关的进程。进......
  • 基于Java开发的工作流审批系统(成熟源码)
    前言目前市场上有很多开源平台没有整合工作流,即使有,也是价格不菲的商业版,来看这篇文章的估计也了解了行情,肯定不便宜。我这个快速开发平台在系统基础功能(用户管理,部门管理…)上整合了工作流,你可以直接用来开发ERP,OA,CRM等企业级应用,不用再担心如何再去花大量的时间集成工作流进来。......
  • 为何学linux及用处
    目前企业使用的操作系统无非就是国产类的,windows和linux类。我们要提升自己的技能,需要学习这两款。我记得在大学时期,学习过windows以及linux,但当时觉得又不常用,就学的模棱两可。毕业之后,你会发现,其实这两种操作系统是很主流的。为什么学?下面就是一些工作中遇到的例子分享一下。我......