linux 内核同步互斥技术之信号量

news2024/11/25 8:22:44

信号量

信号量允许多个进程同时进入临界区,大多数情况下只允许一个进程进入临界区,把信号量的计数值设置为 1,即二值信号量,这种信号量称为互斥信号量。可允许多个锁持有者。
和自旋锁相比,信号量适合保护比较长的临界区,因为竞争信号量时进程可能睡眠和再次唤醒,代价很高。中断服务函数不能进行睡眠,因此信号量不能用于中断当中
信号量的使用流程:
定义一个信号量
    ↓
初始化信号量
    ↓
获得信号量(减操作)
    ↓
释放信号量(加操作)

内核使用的信号量定义如下:
include/linux/semaphore.h
struct semaphore {
    raw_spinlock_t      lock;
    unsigned int        count;
    struct list_head    wait_list;
};
成员 lock 是自旋锁,用来保护信号量的其他成员。
成员 count 是计数值,表示还可以允许多少次进入临界区。
成员 wait_list 是等待进入临界区的进程链表。
struct semaphore_waiter {
    struct task_struct *task;
    bool up;
    struct list_head list;
};

初始化静态信号量的方法如下。
(1)    __SEMAPHORE_INITIALIZER(name, n):指定名称和计数值,允许同时n 次进入临界区。
(2)    DEFINE_SEMAPHORE(name):初始化一个互斥信号量。
在运行时动态初始化信号量的方法如下:
static inline void sema_init(struct semaphore *sem, int val);
参数 val 指定允许同时进入临界区的数量。
获取信号量的函数如下。
(1) void down(struct semaphore *sem);
获取信号量,如果计数值是 0,进程深度睡眠。
(2) int down_interruptible(struct semaphore *sem);
获取信号量,如果计数值是 0,进程轻度睡眠(可以被系统消息打断,该函数的调用允许中断)。如果返回0,表示获得信号量正常返回,如果被信号打断,返回-EINTR。
(3) int down_killable(struct semaphore *sem);
获取信号量,如果计数值是 0,进程中度睡眠(可以因为受到致命信号而被唤醒)。
(4) int down_trylock(struct semaphore *sem);
获取信号量,如果计数值是 0,进程不等待不会导致调用者睡眠。
(5) int down_timeout(struct semaphore *sem, long jiffies);
获取信号量,指定等待的时间。
释放信号量的函数如下:
void up(struct semaphore *sem);


使用示例

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kthread.h> 
#include <linux/semaphore.h> 
#include <linux/delay.h>

int num[2][5]= { {
        0,2,4,6,8
    }
    , {
        1,3,5,7,9
    }
}
;
struct semaphore sem_first;
struct semaphore sem_second;
struct task_struct * task1;
struct task_struct * task2;

int thread_print_first(void *p) {
    int i;
    int *num=(int *)p;
    if(kthread_should_stop()){
        return 0;
    }
    printk(KERN_ALERT"Hello World:first\n");
    for (i=0;i<5;i++) {
        down(&sem_first);
        printk(KERN_ALERT"Hello World:%d\n",num[i]);
        up(&sem_second);
    }
    do {
        msleep(1000);
    }
    while(!kthread_should_stop());
    return 0;
}

int thread_print_second(void *p) {
    int i;
    int *num=(int *)p;
    if(kthread_should_stop()){
        return 0;
    }
    printk(KERN_ALERT"Hello World:second\n");
    for (i=0;i<5;i++) {
        down(&sem_second);
        printk(KERN_ALERT"Hello World:%d\n",num[i]);
        up(&sem_first);
    }
    do {
        msleep(1000);
    }
    while(!kthread_should_stop());
    return 0;
}

static int hello_init(void) {
    printk(KERN_ALERT"Hello World enter\n");
    sema_init(&sem_first,1);
    sema_init(&sem_second,0);
    task1 = kthread_create(thread_print_first,num[0],"first");
    if(IS_ERR(task1)) {
        printk(KERN_ALERT"kthread_create error!\n");
        return -1;
    }
    task2 = kthread_create(thread_print_second,num[1],"second");
    if(IS_ERR(task2)) {
        printk(KERN_ALERT"kthread_create error!\n");
        kthread_stop(task1);
        return -1;
    }
    wake_up_process(task1);
    wake_up_process(task2);
    return 0;
}

static void hello_exit(void) {
    int ret;
    if (!IS_ERR(task1)) {
        ret = kthread_stop(task1);
        printk("<<<<<<<<task1 exit, ret = %d\n", ret);
    }
    if (!IS_ERR(task2)) {
        ret = kthread_stop(task2);
        printk("<<<<<<<<task2 exit, ret = %d\n", ret);
    }
    printk(KERN_ALERT"hello world exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1287731.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PostgreSql HOT 技术

摘自唐成的《PostgreSQL修炼之道&#xff1a;从小工到专家&#xff08;第2版&#xff09;》。 一、概述 因为多版本的原因&#xff0c;当 PostgreSQL 中更新一行时&#xff0c;实际上原数据行并不会被删除&#xff0c;只是插入了一个新行。如果表上有索引&#xff0c;而更新的…

身份统一管理创新与优化 ——华为云OneAccess应用身份管理服务的2023年

2023年&#xff0c;随着云计算、物联网、人工智能等技术的快速发展&#xff0c;企业面临着数字化转型的巨大挑战与机遇。身份统一管理是企业数字化转型的基础&#xff0c;也是业务发展的关键。如何高效、安全、灵活地实现身份统一管理&#xff0c;成为企业亟待解决的首要课题。…

uniapp多行文本展开或收起(兼容h5、微信小程序,其它未测试)

文章目录 一、效果图展示1、收起2、展开3、文本过短时隐藏按钮【查看更多、收起】 二、代码实现原理&#xff1a;判断文本是否过短1、html2、css3、 js&#xff08;1&#xff09;data数据定义&#xff08;2&#xff09;获取文本高度&#xff08;3&#xff09; 获取行数&#xf…

典型的ETL使用场景

典型的ETL使用场景 ETL( Extract&#xff0c;Transform&#xff0c;Load)是一种用于数据集成和数据转换的常用技术。它主要用于从多个数据源中提取数据&#xff0c;对数据进行清洗、转换和整合&#xff0c;最后加载到目标系统中。ETL 的使用场景非常广泛&#xff0c;下面将介绍…

StringBuffer类和StringBuilder类的相关知识点

首先这俩个类都是可变序列&#xff0c;与String类不同String类是不可变序列&#xff0c;StringBuffer和StringBuilder 他们是将数据存储在char value[] 待会会给大家看一下源码&#xff0c;这俩个类相当于是String类的升级版&#xff0c;它可以让我们对字符串的操作更加的便捷…

探秘 Sass 之路:掌握强大的 CSS 预处理器(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

【开源】基于Vue.js的实验室耗材管理系统

文末获取源码&#xff0c;项目编号&#xff1a; S 081 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S081。} 文末获取源码&#xff0c;项目编号&#xff1a;S081。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 耗材档案模块2.2 耗材入库模块2.3 耗…

shiny的图片如何插入,为什么会裂开?

因为你没有把资源放在内部&#xff1a; Shiny学习(二) ||构建用户界面 - 简书d 当然也有例外比如&#xff1a; shiny-如何在 Shinydashboard R 中 dashboard 标题的中心显示图像&#xff1f; - 糯米PHP

羊大师提问鲜羊奶冷冻还好喝吗?

羊大师提问鲜羊奶冷冻还好喝吗&#xff1f; 在当今追求健康、养生的时代背景下&#xff0c;各种新奇的饮食趋势层出不穷。鲜羊奶冷冻成为了备受追捧的美食新潮流。不仅具备饮食的功能&#xff0c;更是一种享受。本文小编羊大师将从鲜羊奶冷冻的制作工艺、营养价值和市场前景等…

Doris 集成 ElasticSearch

Doris-On-ES将Doris的分布式查询规划能力和ES(Elasticsearch)的全文检索能力相结合,提供更完善的OLAP分析场景解决方案: (1)ES中的多index分布式Join查询 (2)Doris和ES中的表联合查询,更复杂的全文检索过滤 1 原理 (1)创建ES外表后,FE会请求建表指定的主机,获取所有…

Apache Doris 在某工商信息商业查询平台的湖仓一体建设实践

本文导读&#xff1a; 信息服务行业可以提供多样化、便捷、高效、安全的信息化服务&#xff0c;为个人及商业决策提供了重要支撑与参考。本文以某工商信息商业查询平台为例&#xff0c;介绍其从传统 Lambda 架构到基于 Doris Multi-Catalog 的湖仓一体架构演进历程。同时通过一…

打CTF比赛/HVV挖洞需要了解哪些知识?

参加CTF&#xff08;Capture The Flag&#xff09;比赛或参与漏洞赏金猎人&#xff08;HVV, HackerOne Vulnerability Hunter&#xff09;活动需要以下关键知识&#xff1a; 1. 网络和系统安全&#xff1a; 理解TCP/IP、DNS、HTTP等网络协议。 掌握操作系统安全&#x…

网上售房管理系统

摘 要 网上售房管理系统,其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面。对于前者要求建立起数据一致性和完整性强、数据安全性好的库。而对于后者则要求应用程序功能完备,易使用等特点。 从而完成完善全面的房屋买卖管理功能&#xff0c;使网上售房管…

关于先更新再缓存这种缓存方案设计的思考

这两天正在做公司缓存方面的设计&#xff0c;然后就把自己的思考过程整理一下。 网上对于这块的内容讲解也非常的多&#xff0c;有些说的也都非常的在理&#xff0c;关于缓存一致性的方案也就那么几种&#xff0c;如&#xff1a;先更新、再删&#xff0c;先删、在更新&#xff…

Linux中的网络配置

本章主要介绍网络配置的方法 网络基础知识查看网络信息图形化界面修改通过配置文件修改 1.1 网络基础知识 一台主机需要配置必要的网络信息&#xff0c;才可以连接到互联网。需要的配置网络信息包括IP、 子网掩码、网关和 DNS 1.1.1 IP地址 在计算机中对IP的标记使用的是3…

JRT导出协议实现

之前实现了JRT的打印客户端实现&#xff0c;这次实现JRT的导出Excel的客户端实现&#xff0c;这样这套框架就成为完全体了。还是一样的设计&#xff0c;不面向具体业务编程&#xff0c;我喜欢面向协议编程&#xff0c;导出一样定义了一套协议。 协议约定&#xff1a; 然后就是…

openEuler操作系统安装

所需要的软件镜像 https://repo.openeuler.org/openEuler-20.03-LTS/ISO/x86_64/ 选择openEuler-20.03-LTS-everything-x86_64-dvd.iso 版本的最完整 如果硬盘空间小可选择openEuler-20.03-LTS-x86_64-dvd.iso 安装步骤 1 选择第一个 install openEuler 20.03-LTS 2 选择语…

鸿蒙Harmony开发初探

一、背景 9月25日华为秋季全场景新品发布会&#xff0c;余承东宣布鸿蒙HarmonyOS NEXT蓄势待发&#xff0c;不再支持安卓应用。网易有道、同程旅行、美团、国航、阿里等公司先后宣布启动鸿蒙原生应用开发工作。 二、鸿蒙Next介绍 HarmonyOS是一款面向万物互联&#xff0c;全…

mysql原理--InnoDB记录结构

1.InnoDB行格式 我们平时是以记录为单位来向表中插入数据的&#xff0c;这些记录在磁盘上的存放方式也被称为 行格式 或者 记录格式 。 设计 InnoDB 存储引擎的大叔们到现在为止设计了4种不同类型的 行格式 &#xff0c;分别是 Compact 、 Redundant 、Dynamic 和 Compressed 行…

罗技鼠标使用接收器和电脑重新配对

罗技鼠标使用接收器和电脑重新配对 文章目录 罗技鼠标使用接收器和电脑重新配对1\. 前言2\. 安装软件3\. 进行配对3.1. 取消之前的配对3.2. 重新配对3.3 配对完成 4\. 报错4.1. 重新配对时显示配对未成功 1. 前言 罗技的鼠标出厂的时候&#xff0c;默认的是将通道一设置为接收…