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

简介: 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) modules
clean:
  make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PAHT) cleals

运行结果

相关文章
|
3月前
|
安全 Linux iOS开发
Binary Ninja 5.1.8104 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
Binary Ninja 5.1.8104 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
397 53
Binary Ninja 5.1.8104 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
|
3月前
|
Linux API iOS开发
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
257 14
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
|
4月前
|
运维 监控 Java
Linux常用命令行大全:14个核心指令详解+实战案例
在服务器管理与开发运维领域,Linux 指令是构建技术能力体系的基石。无论是日常的系统监控、文件操作,还是复杂的服务部署与故障排查,熟练掌握指令的使用逻辑都是提升工作效率的核心前提。然而,对于初学者而言,Linux 指令体系往往呈现出“参数繁多易混淆”“组合使用门槛高”“实际场景适配难”等痛点——例如 ls 命令的 -l 与 -a 参数如何搭配查看隐藏文件详情,grep 与管道符结合时如何精准过滤日志内容,这些问题常常成为技术进阶的阻碍。
|
4月前
|
数据管理 Linux iOS开发
Splunk Enterprise 9.4.5 (macOS, Linux, Windows) - 机器数据管理和分析
Splunk Enterprise 9.4.5 (macOS, Linux, Windows) - 机器数据管理和分析
149 0
|
10月前
|
Linux
linux常用命令详细说明以及案例
本文介绍了Linux中几个常用的命令及其用法,包括:`ls`(列出目录内容)、`cd`(切换目录)、`mkdir`(创建目录)、`rm -p`(删除目录及内容)和`mv`(移动或重命名文件/目录)。每个命令都配有详细说明、语法格式、常见选项及实用案例,帮助用户更好地理解和使用这些基础命令。内容源自[linux常用命令详细说明以及案例](https://linux.ciilii.com/show/news-285.html)。
388 159
|
10月前
|
Linux
linux命令详细说明以及案例
本文介绍了常用的 Linux 命令及其详细说明和示例,包括:`ls`(列出目录内容)、`cd`(更改目录)、`rm` 和 `mv`(删除与移动文件)、`grep`(搜索文本)、`cat`(显示文件内容)以及 `chmod`(更改文件权限)。每个命令均配有功能描述、选项说明及实际案例,帮助用户更好地掌握 Linux 命令的使用方法。
621 157
|
Unix Linux iOS开发
Splunk Enterprise 10.0.0 (macOS, Linux, Windows) - 搜索、分析和可视化,数据全面洞察平台
Splunk Enterprise 10.0.0 (macOS, Linux, Windows) - 搜索、分析和可视化,数据全面洞察平台
146 0
|
8月前
|
数据挖掘 Linux 数据库
服务器数据恢复—Linux系统服务器数据恢复案例
服务器数据恢复环境: linux操作系统服务器中有一组由4块SAS接口硬盘组建的raid5阵列。 服务器故障: 服务器工作过程中突然崩溃。管理员将服务器操作系统进行了重装。 用户方需要恢复服务器中的数据库、办公文档、代码文件等。
|
8月前
|
运维 监控 中间件
Linux运维笔记 - 如何使用WGCLOUD监控交换机的流量
WGCLOUD是一款开源免费的通用主机监控工具,安装使用都非常简单,它可以监控主机、服务器的cpu、内存、磁盘、流量等数据,也可以监控数据库、中间件、网络设备
|
10月前
|
监控 Linux
Linux基础:文件和目录类命令分析。
总的来说,这些基础命令,像是Linux中藏匿的小矮人,每一次我们使用他们,他们就把我们的指令准确的传递给Linux,让我们的指令变为现实。所以,现在就开始你的Linux之旅,挥动你的命令之剑,探索这个充满神秘而又奇妙的世界吧!
184 19