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

运行结果

相关文章
|
1月前
|
Ubuntu Linux Python
Tkinter错误笔记(一):tkinter.Button在linux下出现乱码
在Linux系统中,使用Tkinter库时可能会遇到中文显示乱码的问题,这通常是由于字体支持问题导致的,可以通过更换支持中文的字体来解决。
109 0
Tkinter错误笔记(一):tkinter.Button在linux下出现乱码
|
27天前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
75 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
2月前
|
NoSQL Linux Redis
linux安装单机版redis详细步骤,及python连接redis案例
这篇文章提供了在Linux系统中安装单机版Redis的详细步骤,并展示了如何配置Redis为systemctl启动,以及使用Python连接Redis进行数据操作的案例。
66 2
|
2月前
|
人工智能 监控 Shell
常用的 55 个 Linux Shell 脚本(包括基础案例、文件操作、实用工具、图形化、sed、gawk)
这篇文章提供了55个常用的Linux Shell脚本实例,涵盖基础案例、文件操作、实用工具、图形化界面及sed、gawk的使用。
386 2
|
2月前
|
Unix Linux 网络安全
python中连接linux好用的模块paramiko(附带案例)
该文章详细介绍了如何使用Python的Paramiko模块来连接Linux服务器,包括安装配置及通过密码或密钥进行身份验证的示例。
72 1
|
2月前
|
监控 Linux Shell
30 个实用的 Linux 命令贴与技巧,提升你的效率(附实战案例)
本文介绍了30个实用的Linux命令及其应用场景,帮助你提升命令行操作效率。涵盖返回目录、重新执行命令、查看磁盘使用情况、查找文件、进程管理、网络状态监控、定时任务设置等功能,适合各水平的Linux用户学习和参考。
|
3月前
|
存储 IDE Unix
Linux 内核源代码情景分析(四)(上)
Linux 内核源代码情景分析(四)
31 1
Linux 内核源代码情景分析(四)(上)
|
1月前
|
存储 Linux
服务器数据恢复—Linux操作系统网站服务器数据恢复案例
服务器数据恢复环境: 一台linux操作系统网站服务器,该服务器上部署了几十个网站,使用一块SATA硬盘。 服务器故障&原因: 服务器在工作过程中突然宕机。管理员尝试重新启动服务器失败,于是将服务器上的硬盘拆下检测,发现很多坏扇区。联系当地的一家数据恢复公司处理,但是没有成功。
|
2月前
|
存储 数据挖掘 Linux
服务器数据恢复—Linux操作系统网站服务器数据恢复案例
服务器数据恢复环境: 一台linux操作系统服务器上跑了几十个网站,服务器上只有一块SATA硬盘。 服务器故障: 服务器突然宕机,尝试再次启动失败。将硬盘拆下检测,发现存在坏扇区
|
2月前
|
Shell Linux Python
python执行linux系统命令的几种方法(python3经典编程案例)
文章介绍了多种使用Python执行Linux系统命令的方法,包括使用os模块的不同函数以及subprocess模块来调用shell命令并处理其输出。
30 0