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

Linux系统看门狗应用编程

目录

  • 看门狗应用编程介绍
    • 打开设备
    • 获取设备支持哪些功能:WDIOC_GETSUPPORT
    • 获取/设置超时时间:WDIOC_GETTIMEOUT、WDIOC_SETTIMEOUT
    • 开启/关闭看门狗:WDIOC_SETOPTIONS
    • 喂狗:WDIOC_KEEPALIVE
  • 看门狗应用编程实战

在产品化的嵌入式系统中,为了使系统在异常情况下能自动复位,一般都需要引入看门狗。看门狗其实就是一个可以在一定时间内被复位的计数器。当看门狗启动后,计数器开始自动计数,经过一定时间,如果没有被复位,计数器溢出就会对CPU 产生一个复位信号使系统重启(俗称“被狗咬”)。系统正常运行时,需要在看门狗允许的时间间隔内对看门狗计数器清零(俗称“喂狗”),不让复位信号产生。如果系统不出问题,程序保证按时“喂狗”,一旦程序跑飞,没有“喂狗”,系统“被咬”复位。

看门狗应用编程介绍

前面已经说到,看门狗其实就是一个可以在一定时间内被复位/重置的计数器,一般叫做看门狗计时器(或看门狗定时器);如果在规定时间内没有复位看门狗计时器,计数器溢出则会对CPU 产生一个复位信号使系统重启,当然有些看门狗也可以只产生中断信号而不会使系统复位。
I.MX6UL/I.MX6ULL SoC 集成了两个看门狗定时器(WDOG):WDOG1 和WDOG2;WDOG2 用于安全目的,而WDOG1 则是一个普通的看门狗,支持产生中断信号以及复位CPU。
Linux 系统中所注册的看门狗外设,都会在/dev/目录下生成对应的设备节点(设备文件),设备节点名称通常为watchdogX(X 表示一个数字编号0、1、2、3 等),譬如/dev/watchdog0、/dev/watchdog1 等,通过这些设备节点可以控制看门狗外设。
在这里插入图片描述
这个watchdog0 其实就是I.MX6U 的WDOG1 所对应的设备节点,从图中可知,除了/dev/watchdog0 之外,还有一个watchdog 设备节点,这个设备节点的名称没有后面的数字编号,这个又是什么意思呢?因为系统中可能注册了多个看门狗设备,/dev/watchdog 设备节点则代表系统默认的看门狗设备;通常这指的就是watchdog0,所以,上图中,/dev/watchdog 其实就等于/dev/watchdog0,也就意味着它俩代表的是同一个硬件外设。
应用层控制看门狗其实非常简单,通过ioctl()函数即可做到!接下来笔者向大家进行介绍。
首先在我们的应用程序中,需要包含头文件<linux/watchdog.h>头文件,该头文件中定义了一些ioctl 指令宏,每一个不同的指令宏表示向设备请求不同的操作,如下所示:

#define WDIOC_GETSUPPORT 		_IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
#define WDIOC_GETSTATUS 		_IOR(WATCHDOG_IOCTL_BASE, 1, int)
#define WDIOC_GETBOOTSTATUS 	_IOR(WATCHDOG_IOCTL_BASE, 2, int)
#define WDIOC_GETTEMP 			_IOR(WATCHDOG_IOCTL_BASE, 3, int)
#define WDIOC_SETOPTIONS 		_IOR(WATCHDOG_IOCTL_BASE, 4, int)
#define WDIOC_KEEPALIVE 		_IOR(WATCHDOG_IOCTL_BASE, 5, int)
#define WDIOC_SETTIMEOUT 		_IOWR(WATCHDOG_IOCTL_BASE, 6, int)
#define WDIOC_GETTIMEOUT 		_IOR(WATCHDOG_IOCTL_BASE, 7, int)
#define WDIOC_SETPRETIMEOUT 	_IOWR(WATCHDOG_IOCTL_BASE, 8, int)
#define WDIOC_GETPRETIMEOUT 	_IOR(WATCHDOG_IOCTL_BASE, 9, int)
#define WDIOC_GETTIMELEFT 		_IOR(WATCHDOG_IOCTL_BASE, 10, int)

比较常用指令包括:WDIOC_GETSUPPORT 、WDIOC_SETOPTIONS 、WDIOC_KEEPALIVE 、
WDIOC_SETTIMEOUT、WDIOC_GETTIMEOUT,说明如下:
在这里插入图片描述

打开设备

首先在调用ioctl()函数之前,需要先打开看门狗设备得到文件描述符,如下所示:

int fd;fd = open("/dev/watchdog", "O_RDWR");
if (0 > fd)fprintf(stderr, "open error: %s: %s\n", "/dev/watchdog", strerror(errno));

获取设备支持哪些功能:WDIOC_GETSUPPORT

使用WDIOC_GETSUPPORT 指令获取看门狗设备支持哪些功能,使用方式如下:
ioctl(int fd, WDIOC_GETSUPPORT, struct watchdog_info *info);
使用WDIOC_GETSUPPORT 指令可以获取设备的信息,调用ioctl()需要传入一个struct watchdog_info
*指针,ioctl()会将获取到的数据写入到info 指针所指向的对象中。struct watchdog_info 结构体描述了看门狗设备的信息,我们来看看struct watchdog_info 结构体的定义:

struct watchdog_info {__u32 options; /* Options the card/driver supports */__u32 firmware_version; /* Firmware version of the card */__u8 identity[32]; /* Identity of the board */
};

options 字段记录了设备支持哪些功能或选项;
firmware_version 字段记录了设备的固件版本号;
identity 字段则是一个描述性的字符串。
我们重点关注的是options 字段,该字段描述了设备支持哪些功能、选项,该字段的值如下(可以是以下任意一个值或多个值的位或关系):

#define WDIOF_OVERHEAT 0x0001 /* Reset due to CPU overheat */
#define WDIOF_FANFAULT 0x0002 /* Fan failed */
#define WDIOF_EXTERN1 0x0004 /* External relay 1 */
#define WDIOF_EXTERN2 0x0008 /* External relay 2 */
#define WDIOF_POWERUNDER 0x0010 /* Power bad/power fault */
#define WDIOF_CARDRESET 0x0020 /* Card previously reset the CPU */
#define WDIOF_POWEROVER 0x0040 /* Power over voltage */
#define WDIOF_SETTIMEOUT 0x0080 /* Set timeout (in seconds) */
#define WDIOF_MAGICCLOSE 0x0100 /* Supports magic close char */
#define WDIOF_PRETIMEOUT 0x0200 /* Pretimeout (in seconds), get/set */
#define WDIOF_ALARMONLY 0x0400 /* Watchdog triggers a management or other external alarm not a reboot */
#define WDIOF_KEEPALIVEPING 0x8000 /* Keep alive ping reply */

一般常见的值包括:WDIOF_SETTIMEOUT、WDIOF_KEEPALIVEPING;WDIOF_SETTIMEOUT 表示设备支持设置超时时间;WDIOF_KEEPALIVEPING 表示设备支持“喂狗”操作,也就是重置看门狗计时器。
使用示例如下:

struct watchdog_info info;if (0 > ioctl(fd, WDIOC_GETSUPPORT, &info)) {fprintf(stderr, "ioctl error: WDIOC_GETSUPPORT: %s\n", strerror(errno));return -1;
}printf("identity: %s\n", info.identity);
printf("version: %u\n", firmware_version);if (0 == (WDIOF_KEEPALIVEPING & info.options))printf("设备不支持喂狗操作\n");
if (0 == (WDIOF_SETTIMEOUT & info.options))printf("设备不支持设置超时时间\n");

获取/设置超时时间:WDIOC_GETTIMEOUT、WDIOC_SETTIMEOUT

使用WDIOC_GETTIMEOUT 指令可获取设备当前设置的超时时间,使用方式如下:

ioctl(int fd, WDIOC_GETTIMEOUT, int *timeout);

使用WDIOC_SETTIMEOUT 指令可设置看门狗的超时时间,使用方式如下:

ioctl(int fd, WDIOC_SETTIMEOUT, int *timeout);

超时时间是以秒为单位,设置超时时间时,不可超过其最大值、否则ioctl()调用将会失败,使用示例如下所示:

int timeout;/* 获取超时时间*/
if (0 > ioctl(fd, WDIOC_GETTIMEOUT, &timeout)) {fprintf(stderr, "ioctl error: WDIOC_GETTIMEOUT: %s\n", strerror(errno));return -1;
}printf("current timeout: %ds\n", timeout);/* 设置超时时间*/
timeout = 10; //10 秒钟
if (0 > ioctl(fd, WDIOC_SETTIMEOUT, &timeout)) {fprintf(stderr, "ioctl error: WDIOC_SETTIMEOUT: %s\n", strerror(errno));return -1;
}

开启/关闭看门狗:WDIOC_SETOPTIONS

设置好超时时间之后,接着便可以开启看门狗计时了,使用WDIOC_SETOPTIONS 指令可以开启看门狗计时或停止看门狗计时,使用方式如下:

ioctl(int fd, WDIOC_SETOPTIONS, int *option);

option 指针指向一个int 类型变量,该变量可取值如下:

#define WDIOS_DISABLECARD 0x0001 /* Turn off the watchdog timer */
#define WDIOS_ENABLECARD 0x0002 /* Turn on the watchdog timer */

WDIOS_DISABLECARD 表示停止看门狗计时,WDIOS_ENABLECARD 则表示开启看门狗计时。
使用示例如下所示:

int option = WDIOS_ENABLECARD; //开启
//int option = WDIOS_DISABLECARD; //停止if (0 > ioctl(fd, WDIOC_SETOPTIONS, &option)) {fprintf(stderr, "ioctl error: WDIOC_SETOPTIONS: %s\n", strerror(errno));return -1;
}

需要注意的是,当调用open()打开看门狗设备的时候,即使程序中没有开启看门狗计时器,当close()关闭设备时,看门狗会自动启动;所以,当打开设备之后,需要使用WDIOC_SETOPTIONS 指令停止看门狗计时,等所有设置完成之后再开启看门狗计时器。

喂狗:WDIOC_KEEPALIVE

看门狗计时器启动之后,我们需要在超时之前,去“喂狗”,否则计时器溢出超时将会导致系统复位或产生一个中断信号,通过WDIOC_KEEPALIVE 指令喂狗,使用方式如下:
ioctl(int fd, WDIOC_KEEPALIVE, NULL);
使用示例如下:

if (0 > ioctl(fd, WDIOC_KEEPALIVE, NULL)) {fprintf(stderr, "ioctl error: WDIOC_KEEPALIVE: %s\n", strerror(errno));
}

看门狗应用编程实战

通过上小节介绍之后,我们已经知道了如何编写应用程序去控制看门狗外设了,本小节我们来编写一个简单地看门狗应用程序,示例代码如下所示:
本例程源码对应的路径为:开发板光盘->11、Linux C 应用编程例程源码->27_watchdog->watchdog_test.c。

/***************************************************************Copyright © ALIENTEK Co., Ltd. 1998-2021. All rights reserved.文件名 : watchdog_test.c作者 : 邓涛版本 : V1.0描述 : 看门狗应用程序示例代码其他 : 无论坛 : www.openedv.com日志 : 初版 V1.0 2021/7/14 邓涛创建***************************************************************/#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <linux/watchdog.h>#define  WDOG_DEV   "/dev/watchdog"int main(int argc, char *argv[])
{struct watchdog_info info;int timeout;int time;int fd;int op;if (2 != argc) {fprintf(stderr, "usage: %s <timeout>\n", argv[0]);exit(EXIT_FAILURE);}/* 打开看门狗 */fd = open(WDOG_DEV, O_RDWR);if (0 > fd) {fprintf(stderr, "open error: %s: %s\n", WDOG_DEV, strerror(errno));exit(EXIT_FAILURE);}/* 打开之后看门狗计时器会开启、先停止它 */op = WDIOS_DISABLECARD;if (0 > ioctl(fd, WDIOC_SETOPTIONS, &op)) {fprintf(stderr, "ioctl error: WDIOC_SETOPTIONS: %s\n", strerror(errno));close(fd);exit(EXIT_FAILURE);}timeout = atoi(argv[1]);if (1 > timeout)timeout = 1;/* 设置超时时间 */printf("timeout: %ds\n", timeout);if (0 > ioctl(fd, WDIOC_SETTIMEOUT, &timeout)) {fprintf(stderr, "ioctl error: WDIOC_SETTIMEOUT: %s\n", strerror(errno));close(fd);exit(EXIT_FAILURE);}/* 开启看门狗计时器 */op = WDIOS_ENABLECARD;if (0 > ioctl(fd, WDIOC_SETOPTIONS, &op)) {fprintf(stderr, "ioctl error: WDIOC_SETOPTIONS: %s\n", strerror(errno));close(fd);exit(EXIT_FAILURE);}/* 喂狗 */time = (timeout * 1000 - 100) * 1000;//喂狗时间设置us微秒、在超时时间到来前100ms喂狗for ( ; ; ) {usleep(time);ioctl(fd, WDIOC_KEEPALIVE, NULL);}
}

示例代码很简单,首先打开看门狗设备,接着使用WDIOC_SETOPTIONS 指令(op = WDIOS_DISABLECARD)先停止看门狗计时器;接着通过atoi 获取到用户传入的超时时间,所以执行该测试程序的时候,需要传入一个参数作为看门狗超时时间。
接着使用WDIOC_SETTIMEOUT 指令设置超时时间,再使用WDIOC_SETOPTIONS 指令(op = WDIOS_ENABLECARD)开启看门狗计时器,看门狗开始工作。接着我们需要在超时时间到来之前,去喂狗,喂狗之后,计时器重置,重新计时;不断地喂狗重置计时器、不让其超时、如果一旦超时系统将会复位重启。
编译示例代码:
在这里插入图片描述
将编译得到的可执行文件拷贝到开发板Linux 系统/home/root 目录下,执行测试程序,譬如启动看门狗,设置超时时间为2 秒钟,如下:
在这里插入图片描述
执行程序之后,开门狗计时器就已经启动了,程序中会不断的喂狗重置计时器,以保证程序不会重启。
现在我们按Ctrl + C 结束程序,结束程序意味着已经停止喂狗了、然后看门狗计时器并没有停止,这样将会导致计时器溢出、发生复位重启:
在这里插入图片描述
当按Ctrl+C 终止进程后,内核打印出“watchdog watchdog0: watchdog did not stop!”信息,表示看门狗计时器还正在计时、未停止。

相关文章:

Linux系统看门狗应用编程

目录看门狗应用编程介绍打开设备获取设备支持哪些功能&#xff1a;WDIOC_GETSUPPORT获取/设置超时时间&#xff1a;WDIOC_GETTIMEOUT、WDIOC_SETTIMEOUT开启/关闭看门狗&#xff1a;WDIOC_SETOPTIONS喂狗&#xff1a;WDIOC_KEEPALIVE看门狗应用编程实战在产品化的嵌入式系统中&…...

Spring MVC 源码- LocaleResolver 组件

LocaleResolver 组件LocaleResolver 组件&#xff0c;本地化&#xff08;国际化&#xff09;解析器&#xff0c;提供国际化支持回顾先来回顾一下在 DispatcherServlet 中处理请求的过程中哪里使用到 LocaleResolver 组件&#xff0c;可以回到《一个请求的旅行过程》中的 Dispat…...

Servlet

Servlet1 简介2 快速入门3 执行流程4 生命周期5 方法介绍6 体系结构7 urlPattern配置8 XML配置1 简介 Servlet是JavaWeb最为核心的内容&#xff0c;它是Java提供的一门动态web资源开发技术。 使用Servlet就可以实现&#xff0c;根据不同的登录用户在页面上动态显示不同内容。 …...

简单的周总结

做一个简单的周总结。 校 OJ 上打了近 7 场比赛&#xff0c;ZR 及其他平台各一两场左右。 头几场打的中规中矩&#xff0c;分数大致在 100-200 左右&#xff0c;与同学分数差别不太大&#xff0c;但也没有很突出。 后面几场比较爆炸&#xff0c;分数一直在 100 以下&#xff0…...

Elasticsearch7.8.0版本进阶——IK中文分词器

目录一、ES 的默认分词器测试示例二、IK 中文分词器2.1、IK 中文分词器下载地址2.2、ES 引入IK 中文分词器2.3、IK 中文分词器测试示例三、ES 扩展词汇测试示例一、ES 的默认分词器测试示例 通过 Postman 发送 GET 请求查询分词效果&#xff0c;在消息体里&#xff0c;指定要分…...

一个阿里P6的说不会接口自动化测试,他不会是自己评的吧...

序 近期和一个阿里的测试工程师交流了一波&#xff0c;他竟然说我不会接口自动化测试&#xff0c;我当场就不服了我说你P6自己评级的吧&#xff0c;今天就带大家好好盘一盘接口自动化&#xff0c;本着以和大家交流如何实现高效的接口测试为出发点&#xff0c;本文包含了我在接…...

规则引擎与风控系统04:风控系统实例(下)

上一节把风控实例的基础代码都撸了出来。接下来再来把核心服务代码和规则文件写出来。 因为有了实体类、Dao,所以接来下就可以写服务类了。之前说过这个实例就是要实现两个目的: 1、一分钟内连续访问三次以上,就会被直接封杀; 2、黑名单用户登录会记录可疑事件。 所以服务类…...

我为什么选择Linux mint 21.1 “Vera“ ? Mint安装优化调教指南(分辨率DPI)

前言&#xff1a;为什么是Mint 笔者算是Linux老用户了&#xff0c;作为一个后端开发&#xff0c;尝试了多种不同发行版。 一开始是Manjaro这种Arch系&#xff0c;但是其对于开发而言实在是太过不稳定&#xff1b;每次滚动更新都要解决很多冲突。不适合当生产力&#xff08;本…...

雅思经验(十四)

剑10 test3 阅读p3这篇阅读比较难做下来&#xff0c;主要是这个题材我们不太熟悉&#xff0c;介绍了一种成为拉皮塔人&#xff0c;他们在太平洋上航行&#xff0c;很多岛屿上都有他们足迹&#xff0c;后来人们发掘、探索他们的历史的故事。1.derelict 与 abandoned 主要是前面的…...

刚来的薪资20k,是我的2倍,我是真的卷不过,真的太变态了

在这个行业爬摸滚打5年了&#xff0c;从最开始点点点的功能测试到现在到现在成为高级测试&#xff0c;工资也翻了几倍&#xff0c;简单的说几句吧 改变的开始 之所以改变的原因很简单&#xff0c;我快被新来的卷死了&#xff0c;新来的本科是某211的&#xff0c;干劲十足&…...

五、DeepWalk、Node2Vec论文精读与代码实战【CS224W】(Datawhale组队学习)

开源内容&#xff1a;https://github.com/TommyZihao/zihao_course/tree/main/CS224W 子豪兄B 站视频&#xff1a;https://space.bilibili.com/1900783/channel/collectiondetail?sid915098 斯坦福官方课程主页&#xff1a;https://web.stanford.edu/class/cs224w 文章目录D…...

学习 Python 之 Pygame 开发魂斗罗(四)

学习 Python 之 Pygame 开发魂斗罗&#xff08;四&#xff09;继续编写魂斗罗1. 创建子弹类2. 根据玩家方向和状态设置子弹发射的位置(1). 站立向右发射子弹(2). 站立向左发射子弹(3). 站立朝上发射子弹(4). 蹲下发射子弹(5). 向斜方发射子弹(6). 奔跑时发射子弹(7). 跳跃时发射…...

Linux 基础知识:指令与shell

目录一、操作系统二、指令三、shell一、操作系统 什么是操作系统&#xff1f; 单纯的操作系统应该是指操作系统内核。内核的作用就是管理计算机的软硬件资源&#xff0c;让计算机在合适的时候干合适的事情。 但是有一个问题&#xff0c;并不是人人都会直接通过内核来操作计算机…...

【数通网络交换基础梳理1】二层交换机、以太网帧、MAC地址数据帧转发原理详解

一、网络模型 万年不变&#xff0c;先从模型结构分析&#xff0c;现在大家熟知的网络模型有两种。第一种是&#xff0c;OSI七层模型&#xff0c;第二种是TCP/IP模型。在实际运用中&#xff0c;参考更多的是TCP/IP模型。 OSI七层模型 TCP/IP模型 不需要全部理解&#xff0c;…...

《分布式技术原理与算法解析》学习笔记Day22

哈希与一致性哈希 在分布式系统中&#xff0c;哈希和一致性哈希是数据索引或者数据分布的常见实现方式。 数据分布设计原则 在分布式数据存储系统中&#xff0c;做存储方案选型时&#xff0c;一般会考虑以下因素&#xff1a; 数据均匀数据稳定节点异构性隔离故障域性能稳定…...

[MySQL]MySQL数据类型

文章目录数据类型分类数值类型tinyint类型bit类型float类型decimal类型字符串类型char类型varchar类型char和varchar对比日期和时间类型enum和set类型数据类型分类 MySQL中&#xff0c;支持各种各样的类型&#xff0c;比如表示数值的整型浮点型&#xff0c;文本、二进制类型、…...

利用steam搬砖信息差赚钱,单账号200+,小白也能轻松上手!

现在很多人在做互联网而且也赚到钱了&#xff0c;但还是有很多人赚不到钱&#xff0c;这是为什么&#xff1f; 这里我不得不说一个词叫做赛道&#xff0c;也就是选择&#xff0c;选择大于努力&#xff0c;项目本身大于一切&#xff0c;90%的人都觉得直播带货赚钱&#xff0c;但…...

树与二叉树与森林的相关性质

文章目录树的度树的性质二叉树的性质二叉树与森林树的度 树的度指的是树内所有节点的度数的最大值。 节点的度&#xff1a;节点所拥有的子树的数量。简单来说&#xff0c;我们直接数分支即可&#xff0c;例如下图&#xff1a; 在这颗二叉树中&#xff0c;节点2的度为2&#…...

MySQL面试题

文章目录MySQL索引Mysql索引分类InnDB索引与MyISAM索引实现有什么区别一个表中如果没有创建索引&#xff0c;那么还会创建B树么&#xff1f;B树原理B树怎么来的B树 叶子节点和非叶子节点B树能存储多少数据&#xff1f;MySQL索引 Mysql索引分类 mysql 索引分为三类&#xff1a…...

【蓝桥OJ—C语言】高斯日记、马虎的算式、第39级台阶

文章目录高斯日记马虎的算式第39级台阶总结高斯日记 题目&#xff1a; 大数学家高斯有个好习惯&#xff1a;无论如何都要记日记。 他的日记有个与众不同的地方&#xff0c;他从不注明年月日&#xff0c;而是用一个整数代替&#xff0c;比如&#xff1a;4210。 后来人们知道&am…...

基于深度学习的三维重建网络PatchMatchNet(二):dtu数据集介绍及PatchMatchNet中加载数据部分代码解析

目录 1.dtu数据集介绍 2. PatchMatchNet中数据加载模块详解(dtu_yao_eval.py) 1.dtu数据集介绍 dtu数据集下载地址:dtu...

一文3000字从0到1实现基于requests框架接口自动化测试项目实战(建议收藏)

requests库是一个常用的用于http请求的模块&#xff0c;它使用python语言编写&#xff0c;在当下python系列的接口自动化中应用广泛&#xff0c;本文将带领大家深入学习这个库 Python环境的安装就不在这里赘述了&#xff0c;我们直接开干。 01、requests的安装 windows下执行…...

【RockerMQ】001-RockerMQ 概述

【RockerMQ】001-RockerMQ 概述 文章目录【RockerMQ】001-RockerMQ 概述一、MQ 概述1、MQ 简介2、MQ 用途限流削峰异步解耦数据收集3、常见 MQ 产品概述对比4、MQ 常见协议二、RocketMQ 概述1、简介2、发展历史一、MQ 概述 1、MQ 简介 MQ&#xff0c;Message Queue&#xff0…...

阿里是如何做Code Review的?

作为卓越工程文化的一部分&#xff0c;Code Review其实一直在进行中&#xff0c;只是各团队根据自身情况张驰有度&#xff0c;松紧可能也不一&#xff0c;这里简单梳理一下CR的方法和团队实践。 一、为什么要CR 提前发现缺陷 在CodeReview阶段发现的逻辑错误、业务理解偏差、性…...

内核调试:一次多线程调试与KASAN检测实例

内核调试&#xff1a;一次多线程调试与KASAN检测实例1. 环境说明2. 问题描述3. 问题排查与定位3.1 线程并发问题&#xff08;减少线程数&#xff09;3.2 轻量地跟踪对象的分配与释放3.3 检查空指针与潜在修改者3.4 KASAN检查4. 总结博主最近遇到一个非常顽固的多线程BUG&#x…...

Java - 数据结构,队列

一、什么是队列 普通队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出FIFO(FirstIn First Out) 入队列&#xff1a;进行插入操作的一端称为队尾&#xff08;Tail/Rear&#xff09; 出队列&#xf…...

ccc-pytorch-感知机算法(3)

文章目录单一输出感知机多输出感知机MLP反向传播单一输出感知机 内容解释&#xff1a; w001w^1_{00}w001​&#xff1a;输入标号1连接标号0&#xff08;第一层&#xff09;x00x_0^0x00​&#xff1a;第0层的标号为0的值O11O_1^1O11​:第一层的标号为0的输出值t&#xff1a;真实…...

LeetCode 225.用队列实现栈

请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。实现 MyStack 类&#xff1a;void push(int x) 将元素 x 压入栈顶。int pop() 移除并返回栈顶元素。int top() …...

【面试】spring控制反转IOC

目录一.说明二.ioc的概念和作用三.优点四.实现机制五.IOC和DI的区别六.设计原则一.说明 1.ioc的概念2.ioc的作用3.ioc的优点4.ioc的实现机制 二.ioc的概念和作用 1.全称Inversion of Control2.控制&#xff1a;创建对象的控制权3.反转&#xff1a;以前对象是程序员主动去new…...

Spring 事务管理详解及使用

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...