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

驱动-原子操作

前面 对并发与竞争进行了实验, 两个 app 应用程序之间对共享资源的竞争访问引起了数据传输错误, 而在 Linux 内核中, 提供了四种处理并发与竞争的常见方法:

分别是原子操作、 自旋锁、 信号量、 互斥体, 这里了解下原子操作

文章目录

  • 参考资料
    • 原子整数操作
    • 原子位操作
  • 测试实验-驱动字符设备运用原子操作
    • 驱动程序源码 atomic.c
    • 编译文件 Makefile
    • 测试程序 app.c
    • 加载驱动 insmod
    • 查看dev 下设备是否生成 ls /dev/device_test
    • 驱动传参测试
  • 总结


参考资料

驱动-并发与竞争
Linux驱动之 原子操作
Linux驱动—原子操作

#原子操作的基本概念
原子操作是指不可中断的一个或一系列操作,即在执行过程中不会被线程调度机制打断,保证在多核/多线程环境下对共享数据的操作是安全的。

“原子” 是化学世界中不可再分的最小微粒, 一切物质都由原子组成。 在 Linux 内核中的原子操作可以理解为“不可被拆分的操作” , 就是不能被更高等级中断抢夺优先的操作。 在 C语言中可以使用以下代码对一个整形变量赋值。

int v;//定义一个 int 类型的变量 v
v = 1;//将 int 类型的变量 v 赋值为 1

而上述代码仍然不是“不可拆分的操作”, C 语言程序仍然需要翻译成汇编指令, 在汇编指令的执行过程中仍可能会有竞争的产生。 而原子操作会将整形变量的操作当成一个整体, 不可再进行分割。 而原子操作又可以进一步细分为“整型原子操作”和“位原子操作”

在 Linux 内核中使用 atomic_t 和 atomic64_t 结构体分别来完成 32 位系统和 64 位系统的
整形数据原子操作, 两个结构体定义在“内核源码/include/linux/types.h”

原子整数操作


#include <linux/types.h>
#include <asm/atomic.h>// 定义原子变量
atomic_t v = ATOMIC_INIT(0);// 常用操作
atomic_read(&v);        // 读取原子变量的值
atomic_set(&v, i);      // 设置原子变量的值为i
atomic_add(i, &v);      // 原子加i
atomic_sub(i, &v);      // 原子减i
atomic_inc(&v);         // 原子加1
atomic_dec(&v);         // 原子减1
atomic_sub_and_test(i, &v); // 减i后测试是否为0
atomic_inc_and_test(&v);    // 加1后测试是否为0
atomic_dec_and_test(&v);    // 减1后测试是否为0

原子位操作


#include <asm/bitops.h>unsigned long word = 0;set_bit(nr, &word);     // 设置第nr位为1
clear_bit(nr, &word);   // 清除第nr位
change_bit(nr, &word);  // 翻转第nr位
test_bit(nr, &word);    // 测试第nr位是否为1
test_and_set_bit(nr, &word);    // 测试并设置位
test_and_clear_bit(nr, &word);  // 测试并清除位
test_and_change_bit(nr, &word); // 测试并翻转位

测试实验-驱动字符设备运用原子操作

为了解决前面实验中并发与竞争的问题, 加入原子整形操作相关实验代码, 在 open()函数和 release()函数中加入原子整形变量 v 的赋值代码, 并且在 open()函数中加入原子整形变量 v 的判断代码, 从而实现同一时间内只允许一个应用打开该设备节点, 以此来
防止共享资源竞争的产生。

这里的open 操作可以看一下简要代码,方便理解。


static atomic64_t v = ATOMIC_INIT(1);//初始化原子类型变量 v,并设置为 1
static int open_test(struct inode *inode,struct file *file)
{
if(atomic64_read(&v) != 1){//读取原子类型变量 v 的值并判断是否等于 1
return -EBUSY;
} a
tomic64_set(&v,0);//将原子类型变量 v 的值设置为 0
//printk("\nthis is open_test \n");
return 0;
}

就是设置了一个原子操作的变量,初始化的默认值是1,在这个数值为1的时候才能进行操作,当一个程序执行后 改变值,那么其它程序就无法执行了。 这个程序执行完成后再改变为默认值,其它程序就能访问执行自己逻辑了。

驱动程序源码 atomic.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/atomic.h>
#include <linux/errno.h>static atomic64_t v=ATOMIC_LONG_INIT(1);static int open_test(struct  inode  *inode,struct file *file){if(atomic64_read(&v)!=1){return -EBUSY;}atomic64_set(&v,0);printk("\n this is open_test \n");return 0;};static ssize_t read_test(struct file *file,char __user *ubuf,size_t len,loff_t *off)
{int ret;char kbuf[10] = "topeet";//定义char类型字符串变量kbufprintk("\nthis is read_test \n");ret = copy_to_user(ubuf,kbuf,strlen(kbuf));//使用copy_to_user接收用户空间传递的数据if (ret != 0){printk("copy_to_user is error \n");}printk("copy_to_user is ok \n");return 0;
}
static char kbuf[10] = {0};//定义char类型字符串全局变量kbuf
static ssize_t write_test(struct file *file,const char __user *ubuf,size_t len,loff_t *off)
{int ret;ret = copy_from_user(kbuf,ubuf,len);//使用copy_from_user接收用户空间传递的数据if (ret != 0){printk("copy_from_user is error\n");}if(strcmp(kbuf,"topeet") == 0 ){//如果传递的kbuf是topeet就睡眠四秒钟ssleep(4);}else if(strcmp(kbuf,"itop") == 0){//如果传递的kbuf是itop就睡眠两秒钟ssleep(2);}printk("copy_from_user buf is %s \n",kbuf);return 0;
}
static int release_test(struct inode *inode,struct file *file)
{//printk("\nthis is release_test \n");atomic64_set(&v,1);  //将原子变量赋值为1 return 0;
}struct chrdev_test
{dev_t  dev_num;  //定义dev_t类型变量来表示设备号int major,minor; //定义int 类型的主设备号和次设备号struct cdev cdev_test;   //定义字符设备struct class *class_test;   //定义结构体变量class 类
};struct chrdev_test dev1; //创建chardev_test类型结构体变量static struct file_operations fops_test = {.owner=THIS_MODULE,//将owner字段指向本模块,可以避免在模块的操作正在被使用时卸载该模块.open = open_test,//将open字段指向chrdev_open(...)函数.read = read_test,//将open字段指向chrdev_read(...)函数.write = write_test,//将open字段指向chrdev_write(...)函数.release = release_test,//将open字段指向chrdev_release(...)函数
};//定义file_operations结构体类型的变量cdev_test_opsstatic int __init chrdev_fops_init(void)//驱动入口函数
{if(alloc_chrdev_region(&dev1.dev_num,0,1,"chrdev_name") < 0){printk("alloc_chrdev_region is error\n");}   printk("alloc_chrdev_region is ok\n");dev1.major=MAJOR(dev1.dev_num);//通过MAJOR()函数进行主设备号获取dev1.minor=MINOR(dev1.dev_num);//通过MINOR()函数进行次设备号获取printk("major is %d\n",dev1.major);printk("minor is %d\n",dev1.minor);使用cdev_init()函数初始化cdev_test结构体,并链接到cdev_test_ops结构体cdev_init(&dev1.cdev_test,&fops_test);dev1.cdev_test.owner = THIS_MODULE;//将owner字段指向本模块,可以避免在模块的操作正在被使用时卸载该模块 cdev_add(&dev1.cdev_test,dev1.dev_num,1);printk("cdev_add is ok\n");dev1.class_test  = class_create(THIS_MODULE,"class_test");//使用class_create进行类的创建,类名称为class_testdevice_create(dev1.class_test,NULL,dev1.dev_num,NULL,"device_test");//使用device_create进行设备的创建,设备名称为device_testreturn 0;
}
static void __exit chrdev_fops_exit(void)//驱动出口函数
{cdev_del(&dev1.cdev_test);//使用cdev_del()函数进行字符设备的删除unregister_chrdev_region(dev1.dev_num,1);//释放字符驱动设备号 device_destroy(dev1.class_test,dev1.dev_num);//删除创建的设备class_destroy(dev1.class_test);//删除创建的类printk("module exit \n");}
module_init(chrdev_fops_init);//注册入口函数
module_exit(chrdev_fops_exit);//注册出口函数
MODULE_LICENSE("GPL v2");//同意GPL开源协议
MODULE_AUTHOR("wang fang chen "); //作者信息

编译文件 Makefile

#!/bin/bash
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
obj-m += atomic.o
KDIR :=/home/wfc123/Linux/rk356x_linux/kernel
PWD ?= $(shell pwd)
all:make -C $(KDIR) M=$(PWD) modulesclean:make -C $(KDIR) M=$(PWD) clean

测试程序 app.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main(int argc,char *argv[])
{int fd;//定义int类型的文件描述符char str1[10]={0};//定义读取缓冲区str1fd=open(argv[1],O_RDWR,0666);//调用open函数,打开输入的第一个参数文件,权限为可读可写//fd=open("/dev/device_test",O_RDWR,0666);//调用open函数,打开输入的第一个参数文件,权限为可读可写if(fd<0){printf("open is error\n");return -1;}printf("open is ok\n");if(strcmp(argv[2],"topeet")==0){write(fd,"topeet",sizeof(str1)); }else if(strcmp(argv[2],"itop")==0){write(fd,"itop",sizeof(str1)); }close(fd);//调用close函数,对取消文件描述符到文件的映射return 0;
}

对测试程序进行编译

aarch64-linux-gnu-gcc -o app app.c -static

加载驱动 insmod

如下,测试实验结果
在这里插入图片描述

查看dev 下设备是否生成 ls /dev/device_test

[root@topeet:/mnt/sdcard]# ls /dev/device_test
/dev/device_test
[root@topeet:/mnt/sdcard]#

驱动传参测试

分别执行 测试传参命令如下,结果如下:

[root@topeet:/mnt/sdcard]# ./app /dev/device_test topeet
open is ok
[root@topeet:/mnt/sdcard]# ./app /dev/device_test itop
open is ok
[root@topeet:/mnt/sdcard]# ./app /dev/device_test topeet &
ice_test i[root@topeet:/mnt/sdcard]# ./app /dev/device_test iopen is ok
top
open is error
[root@topeet:/mnt/sdcard]#

在这里插入图片描述

单独执行传参命令验证实验,是没有问题的。两个不同参数同步执行 时候,第二个就执行失败了。 这里起作用的就是 原子操作的效果。

总结

  • 原子操作可以理解为一个计数器,一个原子变量,更具原子变量的值是否是预设的值来保护程序,防止程序资源竞争

相关文章:

驱动-原子操作

前面 对并发与竞争进行了实验&#xff0c; 两个 app 应用程序之间对共享资源的竞争访问引起了数据传输错误&#xff0c; 而在 Linux 内核中&#xff0c; 提供了四种处理并发与竞争的常见方法&#xff1a; 分别是原子操作、 自旋锁、 信号量、 互斥体&#xff0c; 这里了解下原子…...

Flutter ListView 详解

ListView 是 Flutter 中用于构建滚动列表的核心组件&#xff0c;支持垂直、水平滚动以及复杂的动态布局。本文将深入解析其核心用法、性能优化策略和高级功能实现&#xff0c;助你打造流畅高效的列表界面。 一、基础篇&#xff1a;快速构建各类列表 1. 垂直列表&#xff08;默…...

关于视频的一些算法内容,不包含代码等

视频算法&#xff1a; 视频降噪&#xff0c; 去除视频中的噪音&#xff0c;提高图像质量 工作原理&#xff1a; 时域降噪&#xff1a;利用相邻帧之间的相似性&#xff0c;通过平均或滤波来减少随机噪声。 空域降噪&#xff1a;在单帧内使用滤波器&#xff08;高斯滤波器&am…...

OpenCV 图形API(43)颜色空间转换-----将 BGR 图像转换为 LUV 色彩空间函数BGR2LUV()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 将图像从BGR色彩空间转换为LUV色彩空间。 该函数将输入图像从BGR色彩空间转换为LUV。B、G和R通道值的传统范围是0到255。 输出图像必须是8位无符…...

keil报错 ..\..\Libraries\CMSIS\stm32f10x.h(298): error: #67: expected a “}“

报错原因&#xff1a; 通常是由于启动文件、头文件定义或驱动选择不一致导致的。以下是一些具体的解决方案&#xff0c;可以帮助你解决这个问题&#xff1a; 检查步骤&#xff1a; 1. 检查启动文件 确保你的启动文件与你的芯片型号相匹配。例如&#xff0c;如果你的芯片是S…...

图像预处理-添加水印

一.ROI切割 类似裁剪图片&#xff0c;但是原理是基于Numpy数组的切片操作(ROI数组切片是会修改原图数据的)&#xff0c;也就是说这个“裁剪”不是为了保存“裁剪”部分&#xff0c;而是为了方便修改等处理。 import cv2 as cv import numpy as npimg cv.imread(../images/dem…...

扩展欧几里得算法【Exgcd】的内容与题目应用

1.简介 exgcd的目的是表示出二元一次不定方程的通解。 形式化地&#xff0c;exgcd算法就是输入a&#xff0c;b&#xff0c;c的值&#xff0c;返回一组x&#xff0c;y&#xff0c;满足 a x b y c axbyc axbyc。 2.1方程无整数解的情况 当 c 不能被 a &#xff0c;b最小公倍…...

OpenCV day5

函数内容接上文&#xff1a;OpenCV day4-CSDN博客 目录 9.cv2.adaptiveThreshold(): 10.cv2.split()&#xff1a; 11.cv2.merge()&#xff1a; 12.cv2.add()&#xff1a; 13.cv2.subtract()&#xff1a; 14.cv2.multiply()&#xff1a; 15.cv2.divide()&#xff1a; 1…...

Spring DI 详解

学习过 IoC 后&#xff0c;就知道我们可以将对象交给 Spring 进行管理&#xff0c;但是我们在一个类会有若干属性&#xff0c;也就是这个类依赖于这若干个属性&#xff0c;那么我们就可以将交给 Spring 管理的对象注入到这个类中&#xff0c;这也就是依赖注入。 依赖注入有三种…...

解锁动态规划的奥秘:从零到精通的创新思维解析(9)

前言&#xff1a; 小编在前几日写了关于动态规划中的多状态dp的问题&#xff0c;此时小编将会讲述一个动态规划我们常常会遇到的一类问题——股票问题&#xff0c;股票问题就类似小编上一篇所讲述的粉刷房子的问题&#xff0c;可以通过一个二维的dp表来代替多个一维的dp表。买卖…...

redis 配置日志和数据存储位置

Redis配置日志和数据存储位置 介绍 Redis是一个开源的高性能键值存储数据库&#xff0c;常用于缓存、消息队列和实时分析等场景。在使用Redis时&#xff0c;我们需要配置日志和数据存储位置&#xff0c;以便更好地管理和监控Redis的运行状态。本文将介绍如何配置Redis的日志和数…...

STL详解 - stack与queue的模拟实现

目录 一、容器适配器 1. 什么是适配器模式 2. stack与queue的底层结构 3. deque的原理与缺陷 3.1 deque的原理 3.2 deque的缺陷 4. 为何选择deque作为默认底层容器 二、stack与queue的模拟实现 1. stack的实现 2. queue的实现 一、容器适配器 1. 什么是适配器模式 适…...

Chromium 134 编译指南 macOS篇:获取源代码(四)

1. 引言 在Chromium 134的开发之旅中&#xff0c;获取源代码是一个至关重要的里程碑。本文将引导您完成这一关键步骤&#xff0c;为后续的编译和开发工作奠定坚实的基础。无论您是出于学习目的&#xff0c;还是计划开发自己的浏览器项目&#xff0c;掌握获取Chromium源码的方法…...

关于 IntelliJ IDEA 中频繁出现的 Kotlin 及其核心作用

关于 IntelliJ IDEA 中频繁出现的 Kotlin 及其核心作用 1. Kotlin 是什么&#xff1f; Kotlin 是由 JetBrains&#xff08;IntelliJ IDEA 的开发商&#xff09;设计的一种现代化编程语言&#xff0c;2016年正式发布&#xff0c;2017年被 Google 指定为 Android 官方开发语言。…...

MYOJ_11700(UVA10591)Happy Number(快乐数)(超快解法:图论思想解题)

原题(English) Let the sum of the square of the digits of a positive integer S0S0​ be represented by S1S1​. In a similar way, let the sum of the squares of the digits of S1S1​ be represented by S2S2​ and so on. If Si1Si​1 for some i≥1i≥1, then the or…...

2843. 统计对称整数的数目

2843. 统计对称整数的数目 题目链接&#xff1a;2843. 统计对称整数的数目 代码如下&#xff1a; class Solution { public:int countSymmetricIntegers(int low, int high) {int res 0;for (int i low;i < high;i) {string s to_string(i);int n s.size();if (n % 2 …...

【模块化拆解与多视角信息6】自我评价:人设构建的黄金50字——从无效堆砌到精准狙击的认知升级

写在最前 作为一个中古程序猿,我有很多自己想做的事情,比如埋头苦干手搓一个低代码数据库设计平台(目前只针对写java的朋友),比如很喜欢帮身边的朋友看看简历,讲讲面试技巧,毕竟工作这么多年,也做到过高管,有很多面人经历,意见还算有用,大家基本都能拿到想要的offe…...

ServletRequestAttributeListener 的用法笔记250417

ServletRequestAttributeListener 的用法笔记250417 以下是关于 ServletRequestAttributeListener 的用法详解&#xff0c;涵盖核心方法、实现步骤、典型应用场景及注意事项&#xff0c;帮助您有效监听请求级别属性&#xff08;ServletRequest 中的属性&#xff09;的变化&…...

大模型在胃十二指肠溃疡预测及诊疗方案制定中的应用研究

目录 一、引言 1.1 研究背景与目的 1.2 国内外研究现状 1.3 研究方法和创新点 二、大模型相关理论基础 2.1 大模型的基本原理 2.2 适用于医疗领域的大模型类型 2.3 大模型在医疗领域的应用现状和潜力 三、胃十二指肠溃疡的疾病特征 3.1 疾病概述 3.2 诊断方法 3.3 …...

第九节:React HooksReact 18+新特性-React 19的use钩子如何简化异步操作?

对比&#xff1a;useEffect vs use处理Promise 代码题&#xff1a;用use改写数据请求逻辑 React 19 use 钩子&#xff1a;异步操作革命性简化方案&#xff08;附完整代码对比&#xff09; 一、useEffect vs use 处理 Promise 核心差异对比 对比维度useEffect 方案use 钩子方案…...

【React】项目的搭建

create-react-app 搭建vite 搭建相关下载 在Vue中搭建项目的步骤&#xff1a;1.首先安装脚手架的环境&#xff0c;2.通过脚手架的指令创建项目 在React中有两种方式去搭建项目&#xff1a;1.和Vue一样&#xff0c;先安装脚手架然后通过脚手架指令搭建&#xff1b;2.npx create-…...

方案精读:华为数字化转型实践案例合集【附全文阅读】

华为数字化转型旨在通过数字化变革实现全连接的智能华为,成为行业标杆,提升客户满意度和运营效率。其以客户为中心,基于 “双轮驱动” 理念,从转意识、方法、文化、组织、模式等方面入手,构建数字化平台,推进数据治理,保障安全,开展业务重构。通过合同 360、产品设计与…...

VScode使用Pyside6(环境篇)

Pyside6的环境搭建&#xff1a; cmd命令窗口输入&#xff1a;pip install pyside6 使用everthing进行查找&#xff1a;&#xff08;非常好用的一款搜索工具 &#xff09; 进入PySide6文件夹中&#xff0c;点击designer.exe,查看是否能够点开。 VScode环境搭建&#xff1a; 下…...

智能云图库-12-DDD重构

本节重点​ 之前我们已经完成了本项目的功能开发。由于本项目功能丰富、代码量大&#xff0c;如果是在企业中维护开发的项目&#xff0c;传统的 MVC 架构可能会让后续的开发协作越来越困难。所以本节鱼皮要从 0 带大家学习一种新的架构设计模式 —— DDD 领域驱动设计。 大纲…...

Linux 网络配置

文章目录 网络基础知识IP地址子网掩码DNS Linux操作系统网络配置 网络基础知识 IP地址 IP地址是用于区分同一个网络中的不同主机的唯一标识。 Internet中的主机要与其他机器通信必须具有一个IP地址&#xff0c;因为网络中传输的数据包必须携带目的IP地址和源IP地址&#xff…...

05-DevOps-Jenkins自动拉取构建代码2

通过前面的操作&#xff0c;已经成功完成了源代码的打包工作&#xff0c;具体操作参见下面的文章&#xff1a; 05-DevOps-Jenkins自动拉取构建代码-CSDN博客 验证打包文件 验证打包后的文件是否存在&#xff0c;进入到Jenkins的工作目录中&#xff0c;找到对应的jar包&#x…...

ESP32之OTA固件升级流程,基于VSCode环境下的ESP-IDF开发,基于阿里云物联网平台MQTT-TLS连接通信(附源码)

目录 1.创建产品和设备 2.准备工作 2.1 获取基础工程 2.2 基本知识概述 2.2.1 OTA升级流程 2.2.2 主题和数据格式 &#xff08;1&#xff09;设备上报版本号 ①请求主题&#xff08;设备 -> 阿里云&#xff09;&#xff1a; ②响应主题&#xff08;阿里云->设备…...

【秣厉科技】LabVIEW工具包——OpenCV 教程(20):拾遗 - imgproc 基础操作(下)

文章目录 前言imgproc 基础操作&#xff08;下&#xff09;8. 霍夫检测9. 滤波与模糊10. 拟合与包围 总结 前言 需要下载安装OpenCV工具包的朋友&#xff0c;请前往 此处 &#xff1b;系统要求&#xff1a;Windows系统&#xff0c;LabVIEW>2018&#xff0c;兼容32位和64位。…...

kafka发送消息,同时支持消息压缩和不压缩

1、生产者配置 nacos中增加配置&#xff0c;和公共spring-kafka配置字段有区分 需要发送压缩消息时&#xff0c;使用该配置类发送即可 import org.apache.kafka.clients.producer.ProducerConfig; import org.springframework.beans.factory.annotation.Autowired; import or…...

AOSP世界时间的更新

在 AOSP&#xff08;Android Open Source Project&#xff09;中&#xff0c;世界时间的更新主要涉及设备时区数据的管理和更新&#xff0c;以确保设备能够正确显示全球各地的时间。AOSP 依赖 IANA 时区数据库&#xff08;也称为 tzdata&#xff09;来提供时区规则和世界时间数…...

Python + 链上数据可视化:让区块链数据“看得懂、用得上”

Python + 链上数据可视化:让区块链数据“看得懂、用得上” 区块链技术的透明性和去中心化特性,使得链上数据成为金融、供应链、NFT 以及 DeFi 领域的关键参考。可是,对于普通用户而言,链上数据往往晦涩难懂,难以直接利用。那么,如何利用 Python 提取、分析并直观展示链上…...

方德桌面操作系统V5.0-G23 vim无法复制粘贴内容

1.修改 Vim 配置文件 rootyuhua-virtualmachine:/etc/docker# sudo vim /usr/share/vim/vim82/defaults.vim 2.在第82行找到set mousea行&#xff0c;将其为set mouse-a。如果文件中没有set mousea&#xff0c;则修改添加set mouse-a。 3.保存文件并退出 Vim&#xff1a; 4…...

[linux] vim 乱码

1. 确保终端支持中文 设置终端编码为 UTF-8,运行: echo $LANG如果不是 UTF-8(如 en_US.UTF-8),你可以设置为: export LANG=zh_CN.UTF-8 export LC_ALL=zh_CN.UTF-8 2. 确保 Vim 使用 UTF-8 编码 打开 .vimrc 或输入以下命令: :set encoding=utf-8 :set fileencodin…...

天洑参加人工智能校企产学研及人才对接活动——走进南京大学人工智能学院

4月15日&#xff0c;人工智能校企产学研及人才对接——走进南京大学人工智能学院活动在南京大学成功举办。此次活动由江苏省人工智能学会、南京大学人工智能学院主办&#xff0c;江苏省工业和信息化厅党组成员、副厅长池宇&#xff0c;南京大学副校长周志华出席。江苏省工业和信…...

33、单元测试实战练习题

以下是三个练习题的具体实现方案&#xff0c;包含完整代码示例和详细说明&#xff1a; 练习题1&#xff1a;TDD实现博客评论功能 步骤1&#xff1a;编写失败测试 # tests/test_blog.py import unittest from blog import BlogPost, Comment, InvalidCommentErrorclass TestBl…...

《AI大模型应知应会100篇》第22篇:系统提示词(System Prompt)设计与优化

第22篇&#xff1a;系统提示词(System Prompt)设计与优化 摘要 在大语言模型&#xff08;LLM&#xff09;应用中&#xff0c;系统提示词&#xff08;System Prompt&#xff09;是控制模型行为的核心工具之一。它不仅定义了模型的身份、角色和行为规范&#xff0c;还直接影响输…...

【KWDB 创作者计划】_深度学习篇---松科AI加速棒

文章目录 前言一、简介二、安装与配置硬件连接驱动安装软件环境配置三、使用步骤初始化设备调用SDK接口检测设备状态:集成到AI项目四、注意事项兼容性散热固件更新安全移除五、硬件架构与技术规格核心芯片专用AI处理器内存配置接口类型物理接口虚拟接口能效比散热设计六、软件…...

【Quest开发】在虚拟世界设置具有遮挡关系的透视窗口

软件&#xff1a;Unity 2022.3.51f1c1、vscode、Meta XR All in One SDK V72 硬件&#xff1a;Meta Quest3 仅针对urp管线 参考了YY老师这篇&#xff0c;可以先看他的再看这个可能更好理解一些&#xff1a;Unity Meta Quest MR 开发&#xff08;七&#xff09;&#xff1a;使…...

Spark on K8s 在vivo大数据平台的混部实战

作者&#xff1a;vivo 互联网大数据团队- Qin Yehai 在离线混部可以提高整体的资源利用率&#xff0c;不过离线Spark任务部署到混部容器集群需要做一定的改造&#xff0c;本文将从在离线混部中的离线任务的角度&#xff0c;讲述离线任务是如何进行容器化、平台上的离线任务如何…...

Mac配置Java的环境变量

刚拿到手的Mac mini M4如何去设置java的环境变量&#xff1f; 第一步&#xff1a; 首先&#xff0c;你先下载好intelliJ IDEA&#xff0c;然后在里面自带的jdk列表里选择你自己想要使用的jdk的版本以及供应商。 下面是我自己使用的jdk版本以及供应商&#xff1a; 第二步&am…...

RPCRT4!OSF_CCONNECTION::OSF_CCONNECTION函数分析之创建一个RPCRT4!OSF_CCALL--RPC源代码分析

RPCRT4!OSF_CCONNECTION::OSF_CCONNECTION函数分析之创建一个RPCRT4!OSF_CCALL 第一部分&#xff1a; 1: kd> p RPCRT4!OSF_CCONNECTION::OSF_CCONNECTION0x167: 001b:77bf6957 393dec35c877 cmp dword ptr [RPCRT4!gfRPCVerifierEnabled (77c835ec)],edi 1: kd> …...

6、事件处理法典:魔杖交互艺术——React 19 交互实现

一、魔杖启灵&#xff1a;交互魔法的本质 "记住&#xff0c;巫师们&#xff01;魔杖的每一次挥动都是与魔法世界的对话&#xff0c;"麦格教授的魔杖在空中划出金色事件流&#xff0c;"React 19的useTransition如同时间转换器&#xff0c;让麻瓜设备也能感知魔杖…...

.net C# 使用Epplus库将Datatable导出到Excel合并首列

最近处理大量数据,需单独导出到首列名称一致的excel,Epplus免费,效率spire高,在Nuget添加Epplus。因为特殊原因,不能使用数据库,只能由数据源导出到excel;最终处理39万行输出到单独的excel文件时间2分钟。 一、EPPlus 基础介绍 ​EPPlus​ 是一个开源的 .NET 库(适用…...

【gpt生成-总览】怎样才算开发了一门编程语言,需要通过什么测试

开发一门真正的编程语言需要经历完整的设计、实现和验证过程&#xff0c;并通过系统的测试体系验证其完备性。以下是分阶段开发标准及测试方法&#xff1a; 一、语言开发核心阶段 1. 语言规范设计&#xff08;ISO/IEC 标准级别&#xff09; ​​语法规范​​&#xff1a;BNF/…...

网络417 路由转发2 防火墙

路由器临时开启路由转发功能 查看节点a网关ip 节点b网关 1.开启路由器路由转发功能。 2.配置到节点a 节点b的网络。 节点a因为和节点b不在同一网段&#xff0c;计划通过网关直达 网关就是中间节点路由器的ip地址 再Ping另一个 计划节点bping节点c ping不通 是因为 修改了…...

HttpSessionAttributeListener 的用法笔记250417

HttpSessionAttributeListener 的用法笔记250417 以下是关于 HttpSessionAttributeListener 的用法详解&#xff0c;涵盖核心方法、应用场景、实现步骤及关键注意事项&#xff0c;帮助您有效监听会话&#xff08;HttpSession&#xff09;中属性的动态变化&#xff1a; 1. 核心功…...

Spring Boot 实现 Excel 导出功能(支持前端下载 + 文件流)

&#x1f9e0; 一、为什么用 EasyExcel&#xff1f; 在 Java 开发中&#xff0c;操作 Excel 的框架主要有&#xff1a; Apache POI&#xff08;经典但慢、内存占用大&#xff09; JXL&#xff08;老旧不维护&#xff09; Alibaba EasyExcel&#xff08;阿里出品&#xff0c;…...

Java动态批量生成logback日志文件

应用场景举个例子&#xff1a; 当我一个服务需要启动n个端口&#xff0c;来监听n个来源的数据&#xff0c;并且处理数据逻辑一致&#xff1b;但是我想要它们的日志分开文件夹来打印&#xff0c;从而更好的分析问题&#xff0c;那么就可以用我下面提供的模版了&#xff1b; 动态…...

从原理到实践:NFS复杂故障处理方法论

#作者&#xff1a;孙德新 文章目录 一、nfs使用概述二、疑难故障现象描述三、原理分析四、解决方案五、优化服务器资源配置&#xff1a;六、故障案例总结七、故障预防建议八、nfs优化方法 一、nfs使用概述 NFS&#xff08;Network File System&#xff09;是一种分布式文件系…...

SAP FI固定资产报错:在折旧范围 30 中的业务与帐面净值规则冲突 - 解决方法

一、问题描述 消息号 AA660 诊断 由于和在区域30中检查的净帐面价值规则相反&#xff0c;不能过帐该凭证。 过程 当输入比例值时会出现此错误。比例值超过过帐金额&#xff0c;如 100 的后续资本化&#xff0c;但该金额的比例折旧为 110。请检查输入项并做需要的更正。 二、…...