当前位置: 首页 > news >正文

Linux源码阅读笔记12-RCU案例分析

在之前的文章中我们已经了解了RCU机制的原理和Linux的内核源码,这里我们要根据RCU机制写一个demo来展示他应该如何使用。

RCU机制的原理

  • RCU(全称为Read-Copy-Update),它记录所有指向共享数据的指针的使用者,当要修改构想数据时,首先创建一个副本,并在副本中修改,所哟访问线程都离开读临界区后,使用者的指针指向修改后的副本,并且删除旧数据。

  • 他是一种在共享数据结构中实现高效读取和低延迟写入操作的技术。在Linux内核中,RCU是一种基于时间窗口的锁机制,通过充分利用多核处理器和内存系统的特性,在保证并发性的同时提供高性能。

代码示例

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>struct RCUStruct {int a;struct rcu_head rcu;
};static struct RCUStruct* Global_pointer;static struct task_struct* RCURDThread1, *RCURDThread2, *RCUWTThread;static int RCURDThreadFunc1(void* argc) {struct RCUStruct* pointer = NULL;while(1) {msleep(5);rcu_read_lock();mdelay(10);pointer = rcu_dereference(Global_pointer);if(pointer)printk("%s : read a = %d\n", __func__, pointer->a);rcu_read_unlock();}return 0;
}static int RCURDThreadFunc2(void* argc) {struct RCUStruct* pointer = NULL;while(1) {msleep(5);rcu_read_lock();mdelay(10);pointer = rcu_dereference(Global_pointer);if(pointer)printk("%s : read a = %d\n", __func__, pointer->a);rcu_read_unlock();}return 0;
}static void MyRCUDel(struct rcu_head* rcuh) {struct RCUStruct* p = container_of(rcuh, struct RCUStruct, rcu);printk("%s : a = %d\n", __func__, p->a);kfree(p);
}static int RCUWTThreadFunc(void* argc) {struct RCUStruct* old_pointer;struct RCUStruct* new_pointer;int value = (unsigned long)argc;while(1) {msleep(10);new_pointer = kmalloc(sizeof(struct RCUStruct), GFP_KERNEL);old_pointer = Global_pointer;*new_pointer = *old_pointer;new_pointer->a = value;rcu_assign_pointer(Global_pointer, new_pointer);call_rcu(&old_pointer->rcu, MyRCUDel);printk("%s : write to new %d\n", __func__, value);value++;}return 0;
}static int __init RCUFuncInit(void) {int value = 2;printk("Prompt:Successfully initialized the kernel module.\n");Global_pointer = kzalloc(sizeof(struct RCUStruct), GFP_KERNEL);RCURDThread1 = kthread_run(RCURDThreadFunc1, NULL, "RCURD1");RCURDThread2 = kthread_run(RCURDThreadFunc2, NULL, "RCURD2");RCUWTThread = kthread_run(RCUWTThreadFunc, (void*)(unsigned long)value, "RCUWT");return 0;
}static void __exit RCUFuncExit(void) {printk("Prompt:Successfully uninstalled kernel module!\n");kthread_stop(RCURDThread1);kthread_stop(RCURDThread2);kthread_stop(RCUWTThread);if(Global_pointer)kfree(Global_pointer);
}module_init(RCUFuncInit);
module_exit(RCUFuncExit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("lenn louis");
  • Makefile
obj-m:=rcu.o	CURRENT_PAHT:=$(shell pwd) 
LINUX_KERNEL:=$(shell uname -r)   LINUX_KERNEL_PATH:=/usr/src/linux-headers-$(LINUX_KERNEL)
all:make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PAHT) modulesclean:make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PAHT) cleals

运行结果

http://www.lryc.cn/news/390580.html

相关文章:

  • 【C++】双线性差值算法实现RGB图像缩放
  • 计算机网络知识普及之四元组
  • 深度探讨网络安全:挑战、防御策略与实战案例
  • “穿越时空的机械奇观:记里鼓车的历史与科技探秘“
  • DevOps CMDB平台整合Jira工单
  • Vue-路由
  • 【Rust入门教程】安装Rust
  • Character.ai因内容审查流失大量用户、马斯克:Grok-3用了10万块英伟达H100芯片
  • Spring源码九:BeanFactoryPostProcessor
  • 大模型笔记1: Longformer环境配置
  • 类和对象(提高)
  • 免费最好用的证件照制作软件,一键换底+老照片修复+图片动漫化,吊打付费!
  • antfu/ni 在 Windows 下的安装
  • Linux 生产消费者模型
  • 深入浅出:MongoDB中的背景创建索引
  • Spring事务十种失效场景
  • JELR-630HS漏电继电器 30-500mA 导轨安装 约瑟JOSEF
  • 如何实现一个简单的链表或栈结构
  • 抖音外卖服务商入驻流程及费用分别是什么?入驻官方平台的难度大吗?
  • “小红书、B站崩了”,背后的阿里云怎么了?
  • nginx的配置文件
  • 艾滋病隐球菌病的病原学诊断方法包括?
  • jQuery Tooltip 插件使用教程
  • 访问者模式在金融业务中的应用及其框架实现
  • .npy格式图像如何进行深度学习模型训练处理,亲测可行
  • XFeat快速图像特征匹配算法
  • 普元EOS学习笔记-低开实现图书的增删改查
  • 动态住宅代理IP详细解析
  • 等保2.0 实施方案之信息软件验证要求
  • 【LeetCode的使用方法】