fmql之字符驱动设备(3)-并发与竞争

news2024/11/17 15:37:34

学会使用设备树后,要学习linux驱动编写中容易出现的”并发与竞争“。

代码是在之前代码的基础上进行修改。

并发与竞争

(本部分来自于正点原子pdf)

什么是并发与竞争,为什么会出现并发与竞争:

要保护的内容是:

什么是原子操作:

Linux提供的API函数

atomic

整形操作

 位操作

自旋锁

信号量 互斥体

代码修改(atomic)

设备结构体

多了atomic_t lock;

设备操作函数

 模块入口/出口函数

__init        :

APP程序

在之前的APP.c中修改,添加了部分内容。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>

/*
 * @description         : main主程序
 * @param - argc        : argv数组元素个数
 * @param - argv        : 具体参数
 * @return              : 0 成功;其他 失败
 */
int main(int argc, char *argv[])
{
    int fd, ret;
    int cnt = 0;
    unsigned char buf[1];

    if(3 != argc) {
        printf("Usage:\n"
               "\t./atomicAPP /dev/gpio-led 1          @ close LED\n"
               "\t./atomicAPP /dev/gpio-led 0          @ open LED\n"
               );
        return -1;
    }

    /* 打开设备 */
    fd = open(argv[1], O_RDWR);
    if(0 > fd) {
        printf("file %s open failed!\r\n", argv[1]);
        return -1;
    }

    /* 将字符串转换为int型数据 */
    buf[0] = atoi(argv[2]);

    /* 向驱动写入数据 */
    ret = write(fd, buf, sizeof(buf));
    if(0 > ret){
        printf("LED Control Failed!\r\n");
        close(fd);
        return -1;
    }

    /* 模拟占用25s LED设备 */
    for(;;) {
        sleep(5);
        cnt++;
        printf("APP running times: %d\r\n", cnt);
        if(cnt >= 5)    break;
    }
    printf("APP running finished\r\n");

    /* 关闭设备 */
    close(fd);

    return 0;

}

代码修改(自旋锁)

代码在atomic.c的基础上修改

自旋锁(上锁、解锁) ,控制的是dev_stats变量。也就是在改变dev_stats变量的值前,要上锁(其他设备不能修改dev_stats值),修改值后,要进行解锁。

代码修改(信号量)

 在spinlock.c的基础上进行修改。

运行

atomic

正点原子pdf:

实际运行:        failed

后来查看代码,发现led_open操作函数的if条件写错了。

因为atomic_dec_and_test函数,是用来上锁的:将lock值减1,然后判断是否为0,如果是,则返回1(上锁成功,设备占用成功),否则返回1。

所以原来的代码是:

if(atomic_dec_and_test(&gpioled.lock))
{ 
    // error
    return -EBUSY;
}

即,设备占用成功,atomic_dec_and_test返回值为1,满足if条件,进入if条件下的语句(但是是error的语句) ,认为设备busy,占用失败。【相互矛盾了不是】

修改代码:

修改代码后:        succeed

 自旋锁

信号量

总结

1. Linux是一个多任务系统。当多个任务共同操作同一段内存或同一个设备(共享资源)时,容易出现并发与竞争的情况。所以要处理对共享资源的并发访问。

2. 并发与竞争出现的几个主要原因:多线程并发访问;抢占式并发访问;中断程序并发访问;SMP(多核)核间并发访问,etc。

3. 在编写驱动的时候,就要注意避免并发核防止竞争访问。不然,会给后期埋下隐患。

4. 什么是共享资源,哪些内容需要保护。如,全局变量,设备结构体,etc。要弄清楚需要保护的内容或数据。

5. 几种处理并发和竞争的方法:原子操作;自旋锁;信号量;互斥体,etc。

  •         1. 原子操作,是指不能进一步分割的操作。一般用于变量或者位操作。e.g 对某个变量进行赋值,将这个赋值的过程作为一个整体进行运行,即一个原子。

                (整形操作)需要用到:atomic_t结构体。初始化、自增、自减函数。

                (位操作)对内存直接操作。

  •         2. 自旋锁,保护结构体变量。        当一个线程访问某共享资源前,要获取相应的锁,此线程不释放锁,其他线程就不能获取。        锁只能被一个线程持有。        如果另一个线程想要获取锁,就处于循环-等待的状态,直至锁可用。

                缺点:等待自旋锁的线程会一直等待,会浪费处理器时间,降低系统性能。

                适用于:短时期的轻量级加锁。       

                注意事项:被自旋锁保护的临界区一定不能调用任何能够引起睡眠和阻塞的API函数。        不能递归申请自旋锁。                取锁之前一定要禁止本地中断,否则可能导致死锁。

                需要:spinlock_t结构体。初始化、加锁、解锁函数。

  •         3. 信号量,用于控制对共享资源的访问。

                特点:可以使线程(等待的)进入休眠状态。        使用信号量会提高处理器的使用效率(不用像自旋锁那样一直在等待)。

                适用于:占用资源比较久的场合。

                缺点:信号量的开销比自旋锁大,因为信号量使线程进入休眠状态后会切换线程。

                注意事项:不能用于中断中。因为中断不能休眠。

                需要:struct semaphore。初始化、获取信号量、释放信号量的函数。

  •         4. 互斥体,即,一次只有一个线程可以访问共享资源,不能递归申请互斥体。

                        适用于:建议需要互斥访问的地方用互斥体。

                        特点:互斥体可以导致休眠。因此中断中不能使用。        和信号量一样,互斥体保护的临界区可以调用引起阻塞的API函数。                不能递归上锁和解锁。

6. 注意事项

        中断中只能使用自旋锁。

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

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

相关文章

基于TSN的实时通信网络延迟评估技术

论文标题&#xff1a;A TSN-based Technique for Real-Time Latency Evaluation in Communication Networks 作者信息&#xff1a; Alberto Morato, Claudio Zunino, Manuel Cheminod, Stefano Vitturi&#xff0c;来自意大利国家研究委员会&#xff0c;CNR-IEIIT。电子邮件:…

深度学习实战TT100K中国交通标志检测【数据集+YOLOv5模型+源码+PyQt5界面】

AI深度学习TT100k交通标志识别 文章目录 研究背景代码下载链接一、效果演示1.1 图像演示1.2 视频演示 二、技术原理2.1 整体流程2.2 TT100K中国交通标志数据集介绍2.3 YOLOV5 TT100K中国交通标志检测原理2.3.1 概述2.3.2 输入层2.3.3 Backbone层2.3.4 Backbone层2.3.5 Head层 2…

【人人保-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

【时时三省】(C语言基础)指针笔试题6

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 笔试题6 首先aa&#xff3b;2&#xff3d;&#xff3b;5&#xff3d;是二维数组 也就是说它有两行第一行是1 2 3 4 5 第二行是6 7 8 9 10 然后&aa取出的数组的地址 &aa1就直接跳到第…

第1章 C++初识

1.1 编写第一个C程序 1.打开Visual Studio点击"创建新项目" 2.点击"空项目"&#xff0c;并点击"下一步" 3.设置"项目名称"并"设置地址" 4.打开项目后&#xff0c;右击"源文件"并选择"添加"的"新建…

国产操作系统(统信UOS)网络安全等级保护基础安全加固

统一操作系统UOS是由多家企业共同打造的中文国产操作系统。 一、设置口令复杂度策略和有效期 首先安装libpam-pwquality依赖包 口令复杂度策略通过libpam-pwquality依赖包进行设置 依赖包的安装命令&#xff1a;sudo apt-get install libpam-pwquality。 依赖包的查看方式执…

新茶饮卷出海,本土化成胜败关键

爱扬格说&#xff1a;“在那海水酣睡的宫殿里&#xff0c;铺满了多少奇珍异宝。”如今&#xff0c;新茶饮品牌正掀起出海狂潮&#xff0c;挖掘来自海外市场的财富机会。 近日&#xff0c;茶百道股价实现十连涨。消息面上&#xff0c;公司在韩国首尔建大站新店正式对外营业。根…

复现 BEVfusion bug集合(4090d)

目录 写在前面的话Bug 汇总1. python版本2. cuda版本3. mmdet3d版本4. mmcv版本5. mmdet版本 后期工作&#xff08;看到numpy说明成功一半&#xff09;6. numpy版本7. timm安装8. yapf 版本 写在前面的话 主要的问题还是mmcv库的问题&#xff0c;这个版本维护太差了&#xff0…

Idea中的导出分包层次结构图(项目结构树)

导出分包层次结构图 在Terminal中, 输入命令&#xff1a;Get-ChildItem “项目地址” | Tree | Out-File -FilePath “输出地址” Get-ChildItem D:\work\workspace\test | Tree | Out-File -FilePath D:\test.txt

HCIP--以太网交换安全(一)

以太网交换安全概述&#xff1a;以太网交换安全是一系列技术和策略的集合&#xff0c;旨在保护以太网交换机免受各种网络攻击和威胁。 端口隔离 一、端口隔离概述&#xff1a; 作用&#xff1a;可以实现同一个VLAN内端口的隔离 优势&#xff1a; 端口隔离功能为用户提供了更…

央企办医布局智慧医康养,环球医疗(2666.HK)让养老有“医”靠

投资传奇查理芒格说&#xff1a;“我给自己设定的目标是追求平常人没有的常识。”只有挖掘出市场潜移默化的趋势&#xff0c;才能抓住投资机遇。 当下&#xff0c;资本市场一个被低估的产业趋势是&#xff0c;医疗健康行业大并购时代悄然开启&#xff0c;头部上市公司对并购产…

日本IT-正社员、契约社员、个人事业主该如何选?

正社員&#xff1a;就是「正规社员」的意思&#xff0c;按照公司的规定而直接雇用&#xff0c;而且没有制定雇用期间&#xff0c;基本上是以终身雇用至退休年龄&#xff08;70岁&#xff09;为前提。而被雇用的一方需要听从公司的业务命令&#xff0c;包括职位或职场的调迁&…

影响6个时序Baselines模型的代码Bug

前言 我是从去年年底开始入门时间序列研究&#xff0c;但直到最近我读FITS这篇文章的代码时&#xff0c;才发现从去年12月25号就有人发现了数个时间序列Baseline的代码Bug。如果你已经知道这个Bug了&#xff0c;那可以忽略本文&#xff5e; 这个错误最初在Informer&#xff0…

【C++】模板、宏、命名空间、

十五、C中的模板templates 本部分讨论C中的模板templates 在别的语言中&#xff0c;比如java、c、c#等托管语言中&#xff0c;模板类似泛型的概念&#xff0c;但模板比泛型要强大得多。模板有点像宏&#xff0c;而泛型却非常受限于类型系统以及其他很多因素。同时模板也是一个…

SQLite数据库管理:深入解析创建数据库、表、索引及用户权限与事务管理

目录 一、SQLite数据库创建 1.1 安装SQLite 1.2 创建数据库 1.3 验证数据库 二、创建表 2.1 基本语法 2.2 数据类型 2.3 创建表的示例 2.4 查看表结构 三、创建索引 3.1 创建索引的语法 3.2 创建索引的示例 3.3 索引的维护 四、管理用户权限 4.1 基于文件系统的权…

动态规划算法:12.简单多状态 dp 问题_打家劫舍_C++

目录 题目链接&#xff1a;LCR 089. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; 一、题目解析 题目&#xff1a; 解析&#xff1a; 二、算法原理 1、状态表示 状态表示&#xff1a; 2、状态转移方程 状态转移方程推理&#xff1a; 3、初始化 dp表初始化: 特殊…

C++(学习)2024.9.25

目录 继承 概念 构造函数 1.派生类与基类构造函数的关系 2.解决方案 &#xff08;1&#xff09;补充基类的无参构造函数 &#xff08;2&#xff09;手动在派生类中调用基类构造函数 1.透传构造 2.委托构造 3.继承构造 3.对象的创建与销毁流程 4.多重继承 (1)概念 …

基于Spring Boot+Vue前后端分离的中医药科普系统设计和实现(协同过滤算法)【原创】

&#x1f388;系统亮点&#xff1a;协同过滤算法&#xff1b; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17 前端&#xff1a; 技术&#xff1a;框架Vue.js&am…

利用Langchain开发框架研发智能体Agent的过程,以及相关应用场景

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下本文主要介绍了利用langchain开发智能体agent的过程。文章首先阐述了项目背景&#xff0c;随后通过给出样例代码&#xff0c;详细展示了执行过程。此外&#xff0c;本文还探讨了该智能体agent在实际应用场景中的运用…

【漏洞复现】灵当CRM multipleUpload.php接口处存在文件上传漏洞

》》》产品描述《《《 灵当CRM致力于为企业提供客户管理数字化、销售管理自动化、服务管理智能化、项目管理一体化的个性化CRM行业解决方案,构建全生命周期的数字化管理体系,实现可持续的业绩增长! 》》》漏洞描述《《《 灵当CRM系统接口multipleUpload.php文件上传漏洞&#x…