Linux内核机制开发 - DEFINE_PER_CPU和DECLARE_PER_CPU

news2024/11/25 13:46:28

By: fulinux
E-mail: fulinux@sina.com
Blog: https://blog.csdn.net/fulinus
喜欢的盆友欢迎点赞和订阅!
你的喜欢就是我写作的动力!

在这里插入图片描述

目录

  • 1. DEFINE_PER_CPU和DECLARE_PER_CPU
    • 1. 1. DEFINE_PER_CPU
    • 1.2. DECLARE_PER_CPU
  • 2. 区别
    • 2.1. 定义与声明:
    • 2.2. 使用场景:
    • 2.3. 编译器处理:
  • 3. 使用方法
  • 4.示例使用 my_counter
  • 5. 总结

参考:Linux内核机制—percpu

1. DEFINE_PER_CPU和DECLARE_PER_CPU

DEFINE_PER_CPU 和 DECLARE_PER_CPU 是 Linux 内核中用于声明和定义 per-CPU 变量的宏。这些宏允许内核在每个 CPU 上拥有独立的变量副本,这对于多处理器系统上的并发编程非常有用,可以避免锁的竞争。

1. 1. DEFINE_PER_CPU

DEFINE_PER_CPU 宏用于定义一个 per-CPU 变量。它通常在内核模块的源代码文件中使用,直接定义一个全局变量。使用DEFINE_PER_CPU 宏定义的变量会被放置在特定的内存区域,每个 CPU 都有自己的副本。
语法:

DEFINE_PER_CPU(type, name);
  • type: 变量的数据类型。
  • name: 变量的名称。

1.2. DECLARE_PER_CPU

DECLARE_PER_CPU 宏用于声明一个 per-CPU 变量。它通常在头文件中使用,用来声明一个 per-CPU 变量,而实际的定义则需要在某个源文件中通过 DEFINE_PER_CPU 来完成。

DECLARE_PER_CPU(type, name);
  • type: 变量的数据类型。
  • name: 变量的名称。

2. 区别

2.1. 定义与声明:

  • DEFINE_PER_CPU 既定义了变量,也声明了它。这意味着你可以在源文件中直接使用 DEFINE_PER_CPU 来创建一个 per-CPU 变量。
  • DECLARE_PER_CPU 只声明变量,实际的定义需要在其他地方使用 DEFINE_PER_CPU 来完成。

2.2. 使用场景:

  • DEFINE_PER_CPU 通常用于源文件中,直接定义 per-CPU 变量。
  • DECLARE_PER_CPU 通常用于头文件中,提供外部接口访问 per-CPU 变量。

2.3. 编译器处理:

  • DEFINE_PER_CPU 会直接在源文件中创建变量的定义。
  • DECLARE_PER_CPU 则只在头文件中声明变量的存在,不会创建实际的变量定义。

3. 使用方法

假设我们有一个 per-CPU 变量 my_counter,我们可以这样声明和定义它:

//per_cpu.h
#ifndef PER_CPU_H
#define PER_CPU_H

DECLARE_PER_CPU(int, my_counter);

#endif /* PER_CPU_H */
//源文件per_cpu.c
#include "per_cpu.h"

DEFINE_PER_CPU(int, my_counter);

一旦 my_counter 被声明和定义,你就可以在内核模块或其他源文件中使用它。可以通过 __get_cpu_var 或 __this_cpu_read 宏来读取当前 CPU 的副本,通过 __set_cpu_var 或 __this_cpu_write 来修改当前 CPU 的副本。
读取 my_counter

int current_cpu_counter = __this_cpu_read(my_counter);

或者

int cpu_id = smp_processor_id();
int counter_value = __get_cpu_var(my_counter)[cpu_id];

修改 my_counter

__this_cpu_write(my_counter, value);

或者:

int cpu_id = smp_processor_id();
__set_cpu_var(my_counter)[cpu_id] = value;

4.示例使用 my_counter

假设你想要在一个内核模块中初始化 my_counter 并在每个 CPU 上递增它。
内核模块 (my_module.c)

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include "per_cpu.h"

static int __init my_module_init(void)
{
    int cpu;

    for_each_online_cpu(cpu) {
        __set_cpu_var(my_counter)[cpu] = 0;  // 初始化每个 CPU 的 my_counter
    }

    printk(KERN_INFO "Module initialized.\n");
    return 0;
}

static void __exit my_module_exit(void)
{
    printk(KERN_INFO "Module removed.\n");
}

module_init(my_module_init);
module_exit(my_module_exit);
MODULE_LICENSE("GPL");

增加计数器的函数 (increment_counter.c)

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include "per_cpu.h"

void increment_my_counter(void)
{
    int cpu_id = smp_processor_id();
    int current_value = __get_cpu_var(my_counter)[cpu_id];
    __set_cpu_var(my_counter)[cpu_id] = current_value + 1;
}

5. 总结

  1. 使用 __this_cpu_read 和 __this_cpu_write 来读取和修改当前 CPU 的副本。
  2. 使用 __get_cpu_var 和 __set_cpu_var 来访问特定 CPU 的副本。
    这样,你就可以在内核模块中使用 my_counter 这个 per-CPU 变量了。如果你有其他具体的需求或问题,请随时告诉我。

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

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

相关文章

mac专业图表绘制软件:OmniGraffle Pro for mac 激活版

OmniGraffle Pro for Mac 是一款功能强大的图表、流程图、快速页面布局、网站线框和图形设计绘制软件。它具备保持线条与形状连接的功能、有效的样式工具&#xff0c;以及简单易用的组织图表能力&#xff0c;能够快速帮助用户制作出色的图形文稿。OmniGraffle Pro 适用于制作从…

“绿色积分引领新风尚:‘我店‘平台重塑消费市场格局“

在数字化浪潮席卷全球的今天&#xff0c;消费市场正经历一场前所未有的深刻变革与重塑。传统商业模式在数字化的大潮中面临严峻挑战&#xff0c;而“我店”平台凭借其开创性的绿色积分体系&#xff0c;犹如破晓之光&#xff0c;照亮了行业前行的道路&#xff0c;迅速成为市场瞩…

visual studio 2019 以及 TwinCAT3 安装教程

环境&#xff1a; 系统&#xff1a;windows11系统&#xff0c;CPU&#xff1a;Inter I5 一.安装visual studio 这里安装版本不要太高&#xff0c;建议2019或者2017的profession就好。如果你电脑上已经有了一个更高的版本&#xff0c;也不用去卸载高版本再安装低版本&#…

电子纸打造智能、自动化、绿色的工作流程

电子纸打造智能、自动化、绿色的工作流程 RFID技术最早在1940年代问世&#xff0c;1980年开始商业化使用。直到现在RFID&#xff08;无线射频识别&#xff09;技术已经深入到我们生活的方方面面。特别是在工业生产、物流运输等领域&#xff0c;RFID技术发挥着越来越重要的作用…

达梦数据库:无法解析的成员访问表达式[GROUP_CONCAT]

目录 异常原因解决1、LISTAGG()&#xff08;推荐&#xff09;2、WM_CONCAT() 异常 原因 达梦数据库没有GROUP_CONCAT()函数 解决 1、LISTAGG()&#xff08;推荐&#xff09; 2、WM_CONCAT() Java结果集映射后&#xff0c;会是一个地址值

北斗三号5G遥测终端机系统在水库大坝安全监测应用

一、概述 我国现有水库大坝9.8万余座&#xff0c;是世界上拥有水库大坝最多的国家。这些水库大坝在防洪、发电、供水、灌溉等方面发挥巨大效益的同时&#xff0c;所存在的安全风险不容忽视。大坝安全监测是大坝安全管理的重要内容&#xff0c;是控制大坝风险的重要措施。大坝安…

java面向对象--继承(构造方法的访问特点)

一、引言 &#xff08; 简单介绍构造方法的特点) 在 Java 中&#xff0c;面向对象编程中的继承机制允许子类继承父类的属性和方法。当涉及到构造方法时&#xff0c;有一些特定的规则需要遵循。以下是在继承中构造方法访问的一些关键特点&#xff1a; 构造方法的访问特点1、构造…

Docker学习(6):Docker Compose部署案例

一、docker-compose部署mysql 1、准备镜像 2、编写my.cnf配置文件 # 服务端参数配置 [mysqld] usermysql # MySQL启动用户 default-storage-engineINNODB # 创建新表时将使用的默认存储引擎 character-set-serverutf8mb4 # 设置mysql服务端默认字符集…

【电控笔记z56】ADRC回路设计(与smo比较)

用在IPM ADRC 估测反电动势 参数变动 : 内部扰动 SMO : 有高频成分 需要低通滤波器滤去 - 需要补偿延迟 两轴同步旋转坐标下做adrc adrc适合去做变化速度比较低的扰动 ADRC : 估测高速变化的扰动 , 需要修改估测器 电机模型 Ld不等于Lq 式7如下蓝色框图 eso等效成一个纯积分…

基于zynq的图像视频数据采集处理项目一

基于zynq的图像视频数据采集处理项目一 文章目录 基于zynq的图像视频数据采集处理项目一1.整体的架构2.整体的时钟和复位设计3.详细方案设计3.1 ps端spi对摄像头的配置&#xff0c;数据的dvp口截断输入3.2 看手册对 IMX2221080P 模式图像解析3.3 拜耳图像格式转换为 RGB 图像3.…

两地三中心异地多活网络

基于阿里云洛神网络全球基础设施及云原生SDN技术&#xff0c;帮助企业客户在云上快速构建两地三中心跨域多活网络&#xff0c;保障企业核心业务在全球多地域的高品质互联。两地三中心多活网络解决方案提供了弹性、安全、高质量的网络能力&#xff0c;结合数据传输服务DTS轻松实…

下一个人工智能趋势令人恐惧

在技​​术进步的昏暗走廊中&#xff0c;我们站在悬崖边&#xff0c;凝视着广阔而难以预测的人工智能未来。 其进化过程中的每一次曲折都伴随着惊叹和恐惧的低语。当风吹过数字树木时&#xff0c;它讲述了各种可能性的故事&#xff0c;但在其歌声中交织着谨慎的音符。 下一个人…

C语言随机数小游戏

目录 前言 一、游戏要求&#xff1a; 二、游戏实现 1.游戏界面 2.游戏主体 3.主函数 4.运行结果&#xff1a; 总结 前言 前面我们学到了C语言随机数的相关知识&#xff0c;我们今天用这个知识做一个有趣的小游戏&#xff0c;会有一点函数的知识&#xff0c;不过后面会…

WPF中的图形对象

前言 在WPF中可以根据需要在前台绘制自己所需要的几何开状&#xff0c;可设置性很丰富&#xff0c;而且在xaml中很好的实时性&#xff0c;如果是设计时还可以考虑使用Blend for Visual Studio来添加元素&#xff0c;它的设计交互性更高。 1、形状基类Shape 为 Ellipse、Poly…

ATG(地空通信)

█ 到底什么是ATG&#xff1f; ATG&#xff0c;就是Air To Ground&#xff0c;空对地通信&#xff0c;也叫地空通信。 它是一种非常特殊的通信技术&#xff0c;专门为天上的飞机提供服务。 简单来说&#xff0c;就是沿着飞机的航线&#xff0c;设置大量的地面基站。基站天线…

Simulink函数如何绑定到状态

Simulink函数的绑定行为 当Simulink函数位于某个状态内时&#xff0c;该函数会绑定到该状态。绑定会导致以下行为&#xff1a; 函数调用只能在状态操作和状态及其子状态内的转换中发生。 当进入状态时&#xff0c;该功能启用。 当状态退出时&#xff0c;该功能被禁用。 例如&…

Mysql——一条SQL语句的执行流程

一、Mysql的体系结构 架构图&#xff1a; Mysql的体系结构主要分为以下几层&#xff1a; 1. Connectors 连接层&#xff1a;负责处理客户端的请求连接。 系统在访问Mysql的服务器之前会先与服务器建立TCP连接&#xff0c;连接成功后Mysql会对TCP传输过来的用户信息做权限验…

新型技术融合推动渲染技术的发展

随着计算机图形学的不断进步&#xff0c;渲染技术作为其核心组成部分&#xff0c;正经历着前所未有的变革与发展。在未来的几年中&#xff0c;AI、量子计算以及新型硬件技术的融合&#xff0c;将为渲染技术带来革命性的突破&#xff0c;进一步推动其在影视制作、游戏设计、建筑…

爬虫基础2

网页请求原理: 在浏览器上输入一个网址,计算机是不理解这个信息的,会向运营商服务器发送请求告知输入网址的IP地址,然后根据IP地址向对应的服务器发送请求,服务器就会返回一个HTML文件,浏览器会解析HTML文件,即我们看到的网页 根据层级关系来进行爬虫 在python里面相同的缩进表…

职场要懂“3不急”,否则走不远

在职场中&#xff0c;我们经常会遇到各种各样的人和事&#xff0c;有的同事能够得到领导的重视和喜爱&#xff0c;有的则始终处于“不温不火”的状态&#xff0c;这其中到底是什么原因导致的呢&#xff1f; 其实&#xff0c;很大一部分原因是因为在工作中犯了一些“急于表现”…