Linux并发控制机制

深入RK3568 I2C总线锁机制:从i2c_transfer看Linux并发控制设计 本文深入剖析了RK3568平台I2C总线并发控制机制,重点解析了i2c_transfer函数如何根据执行上下文动态选择锁策略。通过分析in_atomic()与irqs_disabled()的判断逻辑,揭示了Linux内核在原子上下文与进程上下文中分别使用i2c_trylock_bus和i2c_lock_bus的并发控制设计,为嵌入式驱动开发者提供了调试和优化I2C总线访问的实践指南。 阅读详情

优快云仅用于增加百度收录权重,排版未优化,日常不维护。请访问:www.hceng.cn 查看、评论。
本博文对应地址: https://hceng.cn/2017/04/05/Linux并发控制/#more
本文主要是简单记录下驱动中的并发控制。

1.并发控制


2.原子变量操作


测试代码:
{% codeblock lang:c [atomic_drv.c] https://github.com/hceng/learn/tree/master/atomic %}
#include <linux/module.h>
#include <linux/init.h>

#include <asm/atomic.h>//原子变量操作的头文件
#include <asm/bitops.h>//原子位操作的头文件

atomic_t a1 = ATOMIC_INIT(1);//定义和设置原子量;
unsigned long int a2;//操作函数传入参数的数据类型是unsigned long int;

static int test_drv_init(void)
{

//测试原子变量操作:
printk("test a1\nKERN_INFO:atomic_read(): a1 =  %d\n", a1); 

atomic_add(4, &a1);
printk("KERN_INFO:atomic_add(): a1 =  %d\n", a1); 

atomic_dec(&a1);
printk("KERN_INFO:atomic_dec(): a1 =  %d\n", a1); 

printk("KERN_INFO:atomic_dec_and_test(): judge_a1 = %d, new_a1 = %d\n",\
	atomic_dec_and_test(&a1),atomic_read(&a1));

//测试原子位操作:
set_bit(0,&a2);//设置a的0位为1;
printk("test a2\nKERN_INFO:set_bit(): a2 =  %ld\n", a2); 

printk("KERN_INFO:test_and_clear_bit(): return_a2 = %d, new_a2 = %ld\n",\
	test_and_clear_bit(0, &a2), a2);

printk("KERN_INFO:test_and_set_bit(): return_a2 = %d, new_a2 = %ld\n",\
	test_and_set_bit(0, &a2), a2);

return 0;

}

static void test_drv_exit(void)
{

}

module_init(test_drv_init);
module_exit(test_drv_exit);

MODULE_LICENSE(“GPL”);
MODULE_AUTHOR(“hceng”);
MODULE_DESCRIPTION(“Learn for atomic”);
{% endcodeblock %}


3.自旋锁


测试代码:
{% codeblock lang:c [lock_drv.c] https://github.com/hceng/learn/blob/master/lock/lock_drv.c %}
/设备驱动中,有些设备只允许打开一次,这里用count计数,lock对count进行保护/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/spinlock.h>//自旋锁头文件

static struct class *testdrv_class;
static struct class_device *testdrv_class_dev;

int count = 0 ;
spinlock_t lock;

static int test_drv_open(struct inode *inode, struct file *file)
{
spin_lock(&lock);
if(count)
{
spin_unlock(&lock);
printk(“kernel: open fail! count = %d\n”,count);
return -EBUSY;
}
count++;
spin_unlock(&lock);
printk(“kernel: open ok! count = %d\n”,count);

return 0;

}

static int test_drv_release(struct inode *inode, struct file *file)
{
spin_lock(&lock);
count–;
spin_unlock(&lock);
printk(“kernel: release ok! count = %d\n”,count);

return 0;

}

static struct file_operations test_drv_fops = {
.owner = THIS_MODULE,
.open = test_drv_open,
.release = test_drv_release,
};

int major;
static int test_drv_init(void)
{
major = register_chrdev(0, “test_drv”, &test_drv_fops);

testdrv_class = class_create(THIS_MODULE, "testdrv");

testdrv_class_dev = device_create(testdrv_class, NULL, MKDEV(major, 0), NULL, "locktest"); 

spin_lock_init(&lock);

printk("kernel: init ok!\n");

return 0;

}

static void test_drv_exit(void)
{
unregister_chrdev(major, “test_drv”);

device_destroy(testdrv_class,  MKDEV(major, 0));	

class_destroy(testdrv_class);

printk("kernel: exit ok!\n");

}

module_init(test_drv_init);
module_exit(test_drv_exit);

MODULE_LICENSE(“GPL”);
MODULE_AUTHOR(“hceng”);
MODULE_DESCRIPTION(“Learn for lock”);
{% endcodeblock %}
{% codeblock lang:c [lock_test.c] https://github.com/hceng/learn/blob/master/lock/lock_test.c %}
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char **argv)
{
int fd;

fd = open("/dev/locktest", O_RDWR);

if (fd < 0)
{
	printf("app: can't open!\n");
}
else printf("app: open ok!\n");

while(1);

return 0;

}
{% endcodeblock %}


4.信号量


{% codeblock lang:c [semaphore_drv.c] https://github.com/hceng/learn/blob/master/semaphore/semaphore_drv.c %}
/设备驱动中,有些资源只能被单一进程访问,这里用sem确保单一访问/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/semaphore.h>//信号量头文件

static struct class *testdrv_class;
static struct class_device *testdrv_class_dev;

struct semaphore sem;

static int test_drv_open(struct inode *inode, struct file *file)
{
printk(“kernel:down before sem.count = %d \n”, sem.count);
down(&sem);
/临界资源/
printk(“kernel:down after sem.count = %d \n”, sem.count);

return 0;

}

static int test_drv_release(struct inode *inode, struct file *file)
{
printk(“kernel:up before sem.count = %d \n”, sem.count);
up(&sem);
printk(“kernel:up after sem.count = %d \n”, sem.count);

return 0;

}

static struct file_operations test_drv_fops = {
.owner = THIS_MODULE,
.open = test_drv_open,
.release = test_drv_release,
};

int major;
static int test_drv_init(void)
{
major = register_chrdev(0, “test_drv”, &test_drv_fops);

testdrv_class = class_create(THIS_MODULE, "testdrv");

testdrv_class_dev = device_create(testdrv_class, NULL, MKDEV(major, 0), NULL, "semaphoretest"); 

sema_init(&sem, 2);//允许同时2个进程访问临界资源

printk("kernel: init ok!\n");

return 0;

}

static void test_drv_exit(void)
{
unregister_chrdev(major, “test_drv”);

device_destroy(testdrv_class,  MKDEV(major, 0));	

class_destroy(testdrv_class);

printk("kernel: exit ok!\n");

}

module_init(test_drv_init);
module_exit(test_drv_exit);

MODULE_LICENSE(“GPL”);
MODULE_AUTHOR(“hceng”);
MODULE_DESCRIPTION(“Learn for semaphore”);
{% endcodeblock %}

{% codeblock lang:c [semaphore_test.c] https://github.com/hceng/learn/blob/master/semaphore/semaphore_test.c %}
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char **argv)
{
int fd;

fd = open("/dev/semaphoretest", O_RDWR);

if (fd < 0)
{
	printf("app: can't open!\n");
}
else printf("app: open ok!\n");

while(1);

return 0;

}
{% endcodeblock %}


5.完成量

RK3399平台开发系列讲解(同步与互斥篇)12.7、Linux并发控制机制总结 Linux驱动开发中使用的并发控制机制有哪些? 阅读详情

相关推荐

68、Linux 内核同步:中断处理、锁机制与并发控制

本文详细介绍了Linux内核同步机制,涵盖中断处理、锁机制与并发控制的核心概念。内容包括中断处理的上下半部分机制、自旋锁和互斥锁的使用场景及注意事项、无锁编程技术如RCU和每个CPU变量,以及内存屏障和缓存效应等关键知识点。文章还提供了实际示例和选择合适锁机制的流程图,帮助开发者编写高效稳定的内核和驱动程序。

4k5l6j7h8的博客 110

linux并发控制详解

对于arm来说,单条汇编指令都是原子的,多核smp也是,因为有总线仲裁所以cpu可以单独占用总线直到指令结束,多核系统中的原子操作通常使用内存栅障(memory barrier)来实现,即一个CPU核在执行原子操作时,其他CPU核必须停止对内存操作或者不对指定的内存进行操作,这样才能避免数据竞争问题。这样, 在CPU0上, 无论是进程上下文, 还是中断上下文获得了自旋锁, 此后, 如果CPU1无论是进程上下文, 还是中断上下文, 想获得同一自旋锁, 都必须忙等待, 这避免一切核间并发的可能性。

m0_46392035的博客 2234

68、Linux内核同步:中断处理、锁机制与并发控制

本文深入探讨了Linux内核中的同步机制,包括中断处理的上下半部分模型、各种锁机制(如自旋锁、互斥锁和读写自旋锁)的使用场景和最佳实践,以及无锁编程技术如per-CPU变量和RCU的实现原理。文章还涵盖了原子操作、内存屏障、缓存效应等关键技术点,旨在帮助开发者更好地理解和应用内核同步技术,提高系统性能和稳定性。

hp777的博客 67

数据库并发控制机制

参考: 允许多个用户同时使用同一数据库的数据库系统称为多用户数据库系统。例如飞机订票数据库系统、银行数据库系统等都是多用户数据库系统。在这样的系统中,在统一时刻并发运行的事务数可达数百上千个。 事务可以一个个地串行执行,即每个时刻只有一个事务运行,其他事务必须等到这个事务结束以后方能运行。但事务执行过程中,有时需要CPU、有时需要I/O,有时需要通信,如果事务串行执行,则许多资源将处于空闲状态。因此,为了充分利用系统资源,发挥数据库共享资源的特点,...

weixin_46308053的博客 1025

Windsurf 入门指南:从安装到实战(免费AI IDE新选择)

本文是Windsurf AI IDE的详细入门指南,涵盖从下载安装到核心功能实战的全过程。通过对比分析,文章指出Windsurf凭借其免费、小白友好的特性及强大的上下文感知能力,成为学习编程和提升开发效率的新选择,特别适合零基础开发者和寻求高效AI编程工具的开发者。

weixin_29237635的博客 853

深度学习入门:使用CMSIS-NN在微控制器上部署模型的完整指南与Python Jupyter实践

CMSIS-NN是ARM为Cortex-M系列微控制器设计的神经网络库。它旨在提供一套高效、轻量级的神经网络API,使得开发者可以在资源受限的微控制器上运行深度学习模型。CMSIS-NN优化了各种常见的神经网络层,如卷积层、全连接层等,确保它们在微控制器上的运行效率。# 定义模型])# 编译模型# 训练模型这样,我们就得到了一个简单的手写数字识别模型。注意:为了简洁和清晰,本文中的代码可能不是最优的或最完整的实现。为了获得完整的项目和更多的优化技巧,请下载完整项目。

m0_57781768的博客 5882

一文读懂三种并发控制机制(封锁、时间戳、有效性确认,大量例子+证明)

文章目录并发控制概述事务特性**定义**并发控制机制串行调度和可串行调度调度串行调度可串行化调度事务和调度的记法冲突可串行化冲突优先图证明使用锁的可串行化实现锁封锁调度器两阶段封锁(2PL)证明多种锁模式的封锁系统共享锁与排他锁相容性矩阵锁的升级更新锁增量锁总结锁的种类事务一致性、冲突和合法调度共享锁、排他锁、更新锁的例子封锁调度器的一种体系结构插入锁锁表锁表的结构封锁信息的数据结构封锁与解锁的处理封锁请求的处理解锁请求的处理数据库元素的层次可封锁元素多粒度的锁警示锁幻象与插入的正确处理树协议基于树封锁的动

GAUSS2021 4358

小程序选项卡以及swiper套用(跨页面)

选项卡tab和swpier之间的套用 其实我之前写过一篇选项卡的切换demo,大家阔以参考一下 小程序多个选项卡切换 那今天写这个demo呢,是因为项目需求,所以仅供参考。 我是拿到了home.wxml的数组下标, 通过url传参的方式去将这个id传到下一个页面, 下一个页面接收以后再将id赋值给对应的tabI或者currentId(swiper 的下标) 实现上一个页面进来以后直接进入对应的页...

Rechal_Mei的博客 3595

《数据库系统概论》11——并发控制

《数据库系统概论》11——并发控制

m0_65036580的博客 1045

【STC8G1K08A串口使用】

STC8G1K08A串口打印“Hello world”

m0_47459564的博客 1万+

GEE土地分类:土地分类精度评定和分类后影像进行(Kmeans,Gmeans,SNIC (Simple Non-Iterative Clustering)聚类分析和滤波(focal_mode)分析

使用聚类分析和滤波分析来进一步处理土地分类后的影像数据。聚类分析可以帮助您识别影像中的相似区域。您可以使用聚类算法,如K均值聚类或层次聚类,将像素分组到具有相似像素值的群集中。这可以帮助您更好地理解图像中的空间模式和结构,并可能揭示有用的信息。滤波分析可以帮助您平滑图像并去除噪声。常见的滤波器包括中值滤波器和高斯滤波器。这些滤波器可以帮助您消除图像中的随机变化,并使其更易于解释和分析。

此星光明博客 2516

Linux设备中的并发控制

说明:如果在读执行单元执行期间,写执行单元已经发生了写操作,那么,读执行单元必须重新获取数据,以确保得到的数据是完整的。3.2.5 R-C-U(读-复制-更新,读和读不互斥,读和写不互斥且开销小,写和写互斥且开销大)3.2.2 考虑中断介入的自旋锁(读和读互斥,读和写互斥,写和写互斥)3.2.3 读写自旋锁(读和读不互斥,读和写互斥,写和写互斥)3.2.4 顺序锁(读和读不互斥,读和写不互斥,写和写互斥)3.2.1 普通自旋锁(读和读互斥,读和写互斥,写和写互斥)(1.2)使用rcu写(挂接回调)

blackhole112358的专栏 572

机器视觉框架源码——解读5(Dock和开源UI)

本文介绍了工业软件中Dock工具面板的使用方法,主要包括三个部分:添加avalonDock引用、修改属性配置(如显示样式和背景色),以及通过MVVM命令实现布局的加载和保存。加载布局通过XmlLayoutSerializer从XML文件恢复界面状态,保存布局则将当前DockManager的布局序列化为XML文件。文章提供了代码示例和截图说明,帮助开发者快速掌握Dock面板的核心功能。

Z's Palace 401

嵌入式Linux驱动开发 - 并发控制机制

嵌入式Linux并发控制机制摘要 本项目探讨了嵌入式Linux驱动开发中的三种并发控制方法:原子操作、自旋锁和信号量/互斥锁。原子操作通过硬件支持的原子指令实现简单计数,适用于轻量级场景;自旋锁采用忙等待机制,适合短时间临界区保护;信号量和互斥锁则通过阻塞等待实现更复杂的同步需求。每种机制各有优缺点:原子操作无阻塞但功能有限,自旋锁避免上下文切换但浪费CPU,信号量支持阻塞但引入调度开销。项目在i.MX6ULL开发板(Linux 4.1.15)上实现,包含完整驱动代码和测试程序,为嵌入式系统并发控制提供实用

愿青春不负梦想 889

「PAT乙级真题解析」Basic Level 1034 有理数四则运算 (问题分析+完整步骤+伪代码描述+提交通过代码)

题设给定两个有理数, 要求输出这两个有理数的和、差、积、商。 如果只是这样, 则问题很简单, 但是题设要求输出的每个有理数必须是最简形式. **所以本题的一个重点是如何将有理数转为题设要求的有理数.**

过美好生活,做高效程序员 3129

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Linux中提供的并发控制机制

由于Linux是一个支持多任务的操作系统,多个进程之间是一种并发的关系。并发是指在操作系统中,一个时间段中有几个程序都处于已启动运行到运行完毕之间,但在任一时间点上只有一个进程在处理器上运行。并发容易导致竞争的问题,竞争就是两个或两个以上的进程同时访问同一资源,从而引起资源的错误。这是操作系统运行所不允许的,所以内核中提供了一些并发控制的机制,用于对公共资源进行保护。   下面描述的相应机制的

134

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

linux kernel rcu 读复制更新 并发控制机制 简介

目录 RCU原理 普通RCU 变种RCU的特点 可睡眠RCU(SRCU) RCU原理 RCU特点:RCU全称Read Copy Update 读复制更新,是一种完全不同于锁的并发控制机制。 主要保护的对象:动态申请的内存,即指针变量。 是扩展性最好的并发控制机制。 RCU主要适用于读者多,写着少的场景 不像锁那样将进程串行化来保护资源,是允许进程并发的。在一些必须串行化才能保护临界区的场景RCU是不适合使用的。 RCU只能保证每个读者读到的数据是有效的,但是不能保证每个数据是最新的。

whatday的专栏 2612

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【Linux驱动开发】并发控制机制:原子操作、自旋锁、信号量、互斥锁详解

Linux驱动开发之并发控制机制:原子操作、自旋锁、信号量、互斥锁详解

imysy_22_的博客 2303

【Linux驱动开发】Linux设备驱动并发控制机制深入分析

基本原子类型} atomic_t;} atomic_t;(i) }自旋锁结构union {#endif#endif#endif。

love131452098的博客 991

Linux 内核锁机制:从自旋锁到 RCU 的并发控制演进

Linux 内核锁机制从轻到重分为原子操作、自旋锁、互斥锁、读写锁和 RCU 五个层级,每个层级针对不同的并发场景。原子操作适用于简单计数器,自旋锁适用于中断上下文和极短临界区,互斥锁适用于可睡眠的长临界区,读写锁适用于读多写少场景,RCU 适用于读远多于写的极致性能场景。选择锁的关键是匹配场景:错误的选择要么导致 CPU 浪费(长临界区用自旋锁),要么导致死锁(中断上下文用互斥锁),要么导致写饥饿(高写频率用读写锁)。

jiang_style的博客 4602

【嵌入式环境下linux内核及驱动学习笔记-(5-驱动的并发控制机制)】

执行流:有开始有结束总体顺序执行的一段代码 又称上下文。对于应用层编程而言,只有任务上下文。 对于内核编程而言,即有任务上下文也有异常上下文。竞态:多任务并行执行时,如果在一个时刻同时操作同一个资源,会引起资源的错乱,这种错乱情形被称为竞态共享资源:可能会被多个任务同时使用的资源。临界区:操作共享资源的代码段。并发控制机制:为了解决竞态,需要提供一种控制机制,来避免在同一时刻使用共享资源,这种机制被称为并发控制机制对互斥锁初始化为可用 --> 对互斥锁进行P操作锁定 --> 临界区 --> 对

weixin_45499326的博客 1682

并发控制 竞态情形 并发控制机制 信号量原理 Linux环境

编程过程中程序员最头疼的两大问题:----- 越界或野指针------多任务编程是才会遭遇简称竞态,就是程序运行时发生的数据混乱错误当并发执行的多任务间同一时刻由于使用共享资源不当而导致共享资源的数据与任何一个任务逻辑都不匹配的错误现象竞态情形错误发生的必要条件:多任务并发执行存在共享资源同一时刻使用即使以上四个条件都满足,竞态情形也不一定发生,这导致竞态情形错误重现成为一个麻烦!!

just show me your code 692

Linux 内核中的 RCU 机制:高性能并发控制的艺术

Linux 内核中的 RCU 机制是一种高性能的并发控制机制,它通过允许多个读者同时访问共享数据,而只在更新时进行同步,从而实现了高并发性能。RCU 的设计思路与企业管理中的并发处理有着密切的联系,它通过高并发处理、数据一致性、无锁设计和垃圾回收等机制,提高了系统的性能和可靠性。工作也要流程化,RCU 就像是系统中的流程规范,它确保了并发访问的有序进行。在实际应用中,我们需要根据具体场景选择合适的并发控制机制,并正确使用 RCU API,以实现高效、可靠的系统设计。

jiang_style的博客 1215

Linux程序并发控制机制

并发(concurrency)指的是多个执行单元同时、并行被执行。而并发的执行单元对共享资源(硬件资源和软件上的全局、静态变量)的访问则容易导致竞态(race conditions)。    SMP是一种紧耦合、共享存储的系统模型,它的特点是多个CPU使用共同的系统总线,因此可访问共同的外设和存储器。    进程与抢占它的进程访问共享资源的情况类似于SMP的多个CPU.    中断可打断正在

savionchen的专栏 492

Linux内核核心机制全景解析:从地址空间到并发控制

操作系统内核是连接应用程序与硬件的中枢,其核心机制涵盖地址空间管理、进程调度、内存虚拟化、中断处理与并发同步等基础能力。理解虚拟内存如何通过MMU实现页表映射与缺页异常处理,掌握进程调度器(如CFS)与同步原语(自旋锁、信号量、RCU)的适用边界,是构建高性能、高可靠系统软件的关键。这些机制共同支撑着现代Linux在服务器、嵌入式及云原生场景中的广泛部署,尤其在ARM/RISC-V异构平台迁移、实时性优化和驱动开发中具有不可替代的技术价值。本文深入剖析Linux内核五大子系统协同逻辑与底层实现原理。

weixin_36012152的博客 278
上一篇: 终端复用软件-Tmux
下一篇: 自己写bootloader
hceng_blog
博客等级 码龄10年 263粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值