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

Linux下多线程的相关概念

🤖个人主页:晚风相伴-CSDN博客

💖如果觉得内容对你有帮助的话,还请给博主一键三连(点赞💜、收藏🧡、关注💚)吧

🙏如果内容有误或者有写的不好的地方的话,还望指出,谢谢!!!

让我们共同进步

下一篇《线程的互斥和同步》敬请期待

目录

🔥Linux线程的概念

👍理解Linux下的线程

线程的异常 

🔥进程VS线程 

线程控制 

🔥线程相关函数 

线程创建

线程等待

线程终止

获取线程ID 

线程分离


🔥Linux线程的概念

比较官方的答案线程是进程中的一条执行流,它是被系统独立调度和分配的基本单位。在一个进程内的多个线程可以共享该进程所拥有的全部资源,并且这些线程可以并发执行。简而言之,线程是程序中一个单一的顺序执行流,允许在单个程序中同时运行多个线程以完成不同的工作,这种技术被称为多线程。

举个例子:一个工厂里面有很多的车间,每个车间里都有许多的工人,每个工人各司其职,完成领导交代的任务。因此这里的工人就可以想象成是线程,每个车间就可以想象成是一个进程,而工厂就可以想象成是一台计算机。每一台计算机内可以拥有许多的进程,而在进程内部又可以有许多条执行流,可以分别处理不同的任务。

👍理解Linux下的线程

我们知道进程具有独立性,每一个进程都有自己独立的PCB(task_struct进程控制块)、地址空间、页表等。

现在有这样的一个技术,我们可以在进程内部创建多个task_struct,并且这些task_struct共享该进程的地址空间、页表等。而这些一个个的task_struct就是线程(执行流)。

在Linux内核中只给进程设计了专门的数据结构,而没有给线程设计专门的数据结构,因为Linux的大佬认为进程和线程在很多处理上都是一样的,没必要再给线程设计专门的数据结构,所以Linux中的线程结构很多都是复用的进程的。因此Linux系统下没有真正意义上的线程结构,而是用进程的机制模拟实现的线程。而Windows系统中有线程相关的数据结构,所以Windows的结构更复杂

综上对于线程更准确的定义是:线程是一个进程内部的控制序列(task_struct)

线程在进程内部运行,本质是在进程地址空间内运行。

线程的异常 

  • 单个线程如果出现除零、野指针问题导致崩溃,进程也会随着崩溃
  • 线程是进程的执行分支,线程出异常,就类似进程出异常,进而触发信号机制,终止进程,进程终止,该进程内的所有线程也就随之退出。
  • 如果在线程中调用exec系列函数或者exit函数也会导致给进程退出。

可以理解为:进程和线程是一体的,所以一荣俱荣,一损俱损

🔥进程VS线程 

进程是资源分配的基本单位,而线程是调度的基本单位。

线程虽然共享进程的数据,但需要有自己的一部分数据:线程ID、寄存器、栈、errno、信号屏蔽字、调度优先级等。

进程的多个线程共享 同一地址空间,因此Text Segment、Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境:

  • 文件描述符表
  • 每种信号的处理方式
  • 当前的工作目录
  • 用户ID和组ID

有了线程的概念之后,在看待之前的进程时,就可以理解为内部只有一条执行流的进程。 

在Linux系统中,CPU是不区分进程和线程的,因为线程也是用进程的机制来模拟实现其功能的,但在CPU看来具有多条执行流的进程比单执行流的进程更加的轻量化,原因如下:

  • 在CPU内部是有缓存的,当执行程序时,是需要先将内存中的代码和数据预读进缓存的。
  • 当一个进程的时间片到了需要被切走时,要把进程对应的上下文数据全部保存起来再切走,并且地址空间、页表等也都需要被切走,而此时的缓存也立即失效了,当下一个进程来了,就需要重新将自身的代码和数据预读进缓存。
  • 而当一个线程的时间片到了需要被切走时,只需要将自己的上下文数据保存起来切走就行了,也不需要重新将代码和数据预读进缓存。

所以Linux下的线程也会被称为轻量级进程。 

进程和线程的关系如下图

线程控制 

因为Linux中是用进程机制模拟实现的线程的,所以Linux并不能直接给我们提供线程相关的接口,只能提供轻量级进程的接口,但在用户层给我们实现了一套多线程的方案,并且以库的方式提供给用户进行使用——pthread线程库(原生线程库)

关于线程库的一些了解

  • 与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“pthrad_”打头的
  • 要使用这些函数库,就需要引入头文件<pthread.h>
  • 链接这些线程函数库是要使用编译器命令的“-lpthread”选项

🔥线程相关函数 

线程创建

参数

  • thread:返回线程ID
  • attr:设置线程的属性,attr为nullptr表示使用默认属性
  • start_routine:是一个函数地址,线程启动后要执行的函数
  • arg:传给线程启动函数的参数

返回值:成功返回0,失败返回错误码 

示例代码 

#include <iostream>
#include <pthread.h>
#include <string>
#include <cstdio>
#include <unistd.h>
using namespace std;void *threadRun(void *args)
{const string name = (char *)args;while (true){cout << name << ", pid: " << getpid() << endl;sleep(1);}
}int main()
{pthread_t tid[5];char name[64];for (int i = 0; i < 5; i++){snprintf(name, sizeof name, "%s-%d", "thread", i + 1);pthread_create(tid + i, nullptr, threadRun, (void *)name);sleep(1);//缓解传参的bug问题}while (true){cout << "main thread, pid: " << getpid() << endl;sleep(3);}return 0;
}

结果演示

其中ps -aL命令可以用来查看线程

LWP就是轻量级进程的意思

从结果就可以看出,每次线程的顺序都是不一样的,这是因为调度器调度的问题。 

一旦一个线程出现了异常,那么整个进程就会退出。

示例代码

void *threadRoutine(void *args)
{int i = 0;while (true){cout << "这是新线程: " << (char *)args << " running..." << endl;sleep(1);int a = 10;a /= 0;//除0错误}cout << "新线程退出..." << endl;return nullptr;
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadRoutine, (void *)"thread 1");return 0;
}

结果演示

线程等待

没错线程也是需要等待的,因为如果主线程不等待,即会引起类似于僵尸问题,导致内存泄漏。

参数:

  • thread:线程ID
  • retval:指向一个指针,该指针指向线程退出的返回值

返回值:成功返回0,失败返回错误码

示例代码 

#include <iostream>
#include <pthread.h>
#include <string>
#include <cstdio>
#include <unistd.h>
using namespace std;void *threadRoutine(void *args)
{int i = 0;while(true){cout << "这是新线程: " << (char*)args << " running..." << endl;sleep(1);if(i++ == 10) break;}cout << "新线程退出..." << endl;return (void*)10;//线程退出的返回值
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadRoutine, (void *)"thread 1");void* ret = nullptr; pthread_join(tid, &ret);cout << "main thread wait done ... mian quit ... new thread quit: " << (long long)ret << endl;return 0;
}

结果演示

不只是可以返回一个数字,返回一组数也是可以的。

示例代码 

void *threadRoutine(void *args)
{int i = 0;int *data = new int[10];while (true){cout << "这是新线程: " << (char *)args << " running..." << endl;sleep(1);data[i] = i;if (i++ == 10)break;}cout << "新线程退出..." << endl;return (void *)data; // 线程退出的返回值
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadRoutine, (void *)"thread 1");int *ret = nullptr;pthread_join(tid, (void**)&ret);cout << "main thread wait done ... mian quit ... new thread quit:" << endl;for (int i = 0; i < 10; i++){cout << ret[i] << " ";}cout << endl;return 0;
}

结果演示

线程终止

如果需要终止某个线程而其它线程不受影响,可以有三种方法:

  1. return,这种方法对主线程不适用,在main函数中return相当于调用exit。
  2. 调用pthread_exit终止自己
  3. 在一个线程中调用pthread_cancel终止同一个进程中的另一个线程。

参数:

  • retval:和线程等待那的参数一样

返回值:无返回值


参数:

  • thread:线程ID

返回值:成功返回0,失败返回错误码

调用pthread_cancel终止的话,那么pthread_join等待接收到的就是常数PTHREAD_CANCELED。

示例代码

void *threadRoutine(void *args)
{int i = 0;while (true){cout << "这是新线程: " << (char *)args << " running..." << endl;sleep(1);if (i++ == 5)break;}cout << "新线程退出..." << endl;pthread_exit((void*)10);
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadRoutine, (void *)"thread 1");void *ret = nullptr;pthread_join(tid, &ret);cout << "main thread wait done ... mian quit ... new thread quit:" << (long long)ret << endl;return 0;
}

结果演示 

获取线程ID 

返回值:线程ID

pthread_create函数会产生一个线程ID,存放在第一个参数指向的地址中,但是这个线程ID和ps -aL命令查看的ID是不一样的,用ps -aL查看的ID是属于进程调度范畴的,因为线程是轻量级进程,是操作系统调度器的最小单位,所以需要一个数值来唯一标识该线程。而pthread_create参数中的线程ID是指向一个虚拟内存单元(这个单元是在地址空间中的共享区),该内存单元的地址即为新创建线程的线程ID。

Linux线程库中提供了pthread_self函数用来获取线程自身的ID,其本质是一个地址。

如图所示: 

示例代码

void *threadRoutine(void *args)
{cout << "pthread_self:" << pthread_self() << endl;cout << "这是新线程: " << (char *)args << " running..." << endl;pthread_exit((void*)10);
}int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadRoutine, (void *)"thread 1");cout << "tid:" << tid << endl;void *ret = nullptr;pthread_join(tid, &ret);cout << "main thread wait done ... mian quit ... new thread quit:" << (long long)ret << endl;return 0;
}

结果演示 

线程的局部存储  

每个线程都可以拥有自己的数据,使用__thread修饰全局变量就可以让每个线程中都各自拥有一个全局变量,这就实现了线程的局部存储。

示例代码

__thread int g_val = 10; //__thread修饰全局变量:线程的局部存储,让每一个线程各自拥有一个全局变量void *threadRoutine(void *args)
{while (true){cout << (char *)args << " : " << g_val << " 地址: " << &g_val << endl;g_val++;sleep(1);break;}return nullptr;
}int main()
{pthread_t tid; // 本质上是一个地址,各自线程的独立属性(独立的栈、id等)pthread_create(&tid, nullptr, threadRoutine, (void *)"thread 1");while (true){cout << "main thread: " << g_val << " 地址: " << &g_val << endl;sleep(1);break;}pthread_join(tid, nullptr);return 0;
}

结果演示

线程分离

在一些场景下,如果我们不关心该线程的退出结果,那么我们对线程进程pthread_join就是一种负担,所以就可以使用线程分离函数pthread_detach,告诉操作系统,让这个线程退出时自动释放资源。 

 

参数:

  • thread:线程ID

返回值:成功返回0,失败返回错误码

可以是线程组内其它线程对目标线程进行分离,也可以是线程自己分离。

示例代码

void *threadRoutine(void *args)
{pthread_detach(pthread_self()); // 线程分离cout << "新线程退出了,并且自己释放了资源" << endl;return nullptr;
}int main()
{pthread_t tid; pthread_create(&tid, nullptr, threadRoutine, (void *)"thread 1");while (true){sleep(1);break;}int n = pthread_join(tid, nullptr);cout << "n: " << n << " strerr: " << strerror(n) << endl;//因为线程自己释放了资源,所以pthread_join会失败return 0;
}

结果演示

 

相关文章:

Linux下多线程的相关概念

&#x1f916;个人主页&#xff1a;晚风相伴-CSDN博客 &#x1f496;如果觉得内容对你有帮助的话&#xff0c;还请给博主一键三连&#xff08;点赞&#x1f49c;、收藏&#x1f9e1;、关注&#x1f49a;&#xff09;吧 &#x1f64f;如果内容有误或者有写的不好的地方的话&…...

在java java.util.Date 已知逝去时间怎么求年月日

在java中&#xff0c;可以使用java.util.Date类来获取年、月和日。以下是一种方法&#xff1a; 首先创建一个java.util.Date对象&#xff0c;表示逝去的时间。 Date pastDate new Date(逝去的时间的毫秒数);然后使用java.util.Calendar类来获取年、月和日。 Calendar calen…...

LeetCode 2928.给小朋友们分糖果 I:Java提交的运行时间超过了61%的用户

【LetMeFly】2928.给小朋友们分糖果 I&#xff1a;Java提交的运行时间超过了61%的用户 力扣题目链接&#xff1a;https://leetcode.cn/problems/distribute-candies-among-children-i/ 给你两个正整数 n 和 limit 。 请你将 n 颗糖果分给 3 位小朋友&#xff0c;确保没有任何…...

【typescript/flatbuffer】在websocket中使用flatbuffer

目录 说在前面场景fbs服务器代码前端typescript代码问题 说在前面 操作系统&#xff1a;Windows11node版本&#xff1a;v18.19.0typescript flatbuffer版本&#xff1a;24.3.25 场景 服务器(本文为golanggin)与前端通信时使用flatbuffer进行序列化与反序列化通信协议为websock…...

构建一个文字冒险游戏:Python 编程实战

在本文中&#xff0c;我们将探索如何使用 Python 创建一个简单的文字冒险游戏。通过这个项目&#xff0c;你将了解到基础的编程技术&#xff0c;包括条件语句、函数和基本的用户输入处理&#xff0c;同时也能体会到文本游戏的魅力和设计的挑战。 项目概述 文字冒险游戏是一种…...

09Linux GDB学习笔记

Linux GDB使用 目录 文章目录 Linux GDB使用先编译文件1.检查安装1.1 安装GDB 2.启动GDB3.退出GDB4.设置断点4.1 在指定行号处设置断点4.2 在指定函数名处设置断点4.3 在指定源文件和行号处设置断点 4.4查看断点信息4.5删除断点5.运行5.1 <font color#ff0000>逐过程&am…...

海外金融牌照

一般来说牌照申请分两个大类&#xff1a;数字货币牌照和外汇牌照。每个国家的牌照具体监管的情况也是不一样的。申请牌照时该如何选择&#xff1f; 今天先说说区块链牌照&#xff0c;具有代表性的有美国msb牌照&#xff0c;加拿大msb牌照&#xff0c;爱沙尼亚数字货币牌照&…...

addEventListener()方法中的几个参数,以及作用

addEventListener() 方法是 JavaScript 中用于处理指定元素的指定事件的函数。它有三个参数&#xff1a; type&#xff08;必需&#xff09;&#xff1a;一个字符串&#xff0c;指定要监听的事件名。 listener&#xff08;必需&#xff09;&#xff1a;一个实现了 EventListen…...

FreeRtos进阶——通用链表的实现方式

通用链表实现方式&#xff08;一&#xff09; struct node_t {struct node_t *next; };struct person {struct node_t node;char *name;int age; };struct dog {struct node_t node;char *name;int age;char *class; };在此链表中&#xff0c;node结构体被放在了最前面&#x…...

【kubernetes】关于k8s集群如何将pod调度到指定node节点(亲和与反亲和等)

目录 一、调度约束 1.1K8S的 List-Watch 机制 ⭐⭐⭐⭐⭐ 1.1.1Pod 启动典型创建过程 二、调度过程 2.1Predicate&#xff08;预选策略&#xff09; 常见的算法 2.2priorities&#xff08;优选策略&#xff09;常见的算法 三、k8s将pod调度到指定node的方法 3.1指定…...

AOP基础

黑马程序员JavaWeb开发教程 文章目录 一、AOP概述二、AOP快速入门2.1 步骤2.2 AOP的使用场景2.3 AOP的优势 三、AOP核心概念3.1 AOP核心概念3.2 AOP执行流程 一、AOP概述 AOP&#xff1a;Aspect Oriented Propragramming(面向切面变成、面向方面编程)其实就是面向特定方法编程…...

EXSI虚拟机新增磁盘并将空间扩充到已有分区

这里写自定义目录标题 1、在EXSI虚拟机中新增一块磁盘配置大小2、确认新磁盘3、格式化新分区4、添加新分区到LVM5、将新增分区添加到已有分区里 1、在EXSI虚拟机中新增一块磁盘配置大小 注意事项&#xff1a; (1)需确保虚拟机已关闭活处于维护模式&#xff0c;避免数据丢失 (2…...

民国漫画杂志《时代漫画》第39期.PDF

时代漫画39.PDF: https://url03.ctfile.com/f/1779803-1248636473-6bd732?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps: 资源来源网络!...

每天一个数据分析题(三百四十二)

根据量化对象是业务行为结果还是财务行为结果&#xff0c;可以将指标分为业务指标及财务指标两大类&#xff0c;以下说法正确的是&#xff1f; A. 财务指标是按照财务规则来对财务情况进行量化的指标 B. 业务指标是按照业务规则来对业务情况进行量化的指标 C. 业务指标需要按…...

c++会员消费积分系统

这段代码实现了一个简单的会员卡管理系统&#xff0c;具有以下功能&#xff1a; 会员开卡&#xff1a;用户可以输入会员的姓名和会员编号&#xff0c;系统将创建新的会员卡并记录相关信息。 消费积分&#xff1a;用户可以输入会员编号和消费积分&#xff0c;系统会根据会员编号…...

如何获知表中数据被删除

目录 1. 使用触发器 (Triggers)示例 2. 使用审计工具 (Audit Tools)示例 3. 使用Binlog (Binary Log)示例 4. 使用应用层记录日志示例 总结 要查询 MySQL 数据库表中的数据何时被删除&#xff0c;可以采取以下几种方法&#xff1a; 1. 使用触发器 (Triggers) 可以在表上创建一…...

机器学习之sklearn基础教程

码到三十五 &#xff1a; 个人主页 机器学习库scikit-learn&#xff08;简称sklearn&#xff09;是Python中一个功能强大的机器学习库&#xff0c;它提供了大量用于数据挖掘和数据分析的工具&#xff0c;包括分类、回归、聚类、降维等算法。文中我们一起简单探讨sklearn的一些基…...

ES升级--04--SpringBoot整合Elasticsearch

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 SpringBoot整合Elasticsearch1.建立项目2.Maven 依赖[ES 官方网站&#xff1a;https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.8/index.html](…...

eclipse如何debug

步骤1&#xff1a;双击显示行数的数字来设置断点 步骤2&#xff1a;点击debug 步骤3&#xff1a;在弹出的窗口点击switch 步骤4&#xff1a;就可以调试了&#xff0c;右边是查看数据的&#xff0c;点击上面的图标进行下一步 步骤5&#xff1a;退出debug 步骤6&#xff1a;…...

无人售货机零售业务成功指南:从市场分析到创新策略

在科技驱动的零售新时代&#xff0c;无人售货机作为一种便捷购物解决方案&#xff0c;正逐步兴起&#xff0c;它不仅优化了消费者体验&#xff0c;还显著降低了人力成本&#xff0c;提升了运营效能。开展这项业务前&#xff0c;深入的市场剖析不可或缺&#xff0c;需聚焦消费者…...

开源代码分享(32)-基于改进多目标灰狼算法的冷热电联供型微电网运行优化

参考文献&#xff1a; [1]戚艳,尚学军,聂靖宇,等.基于改进多目标灰狼算法的冷热电联供型微电网运行优化[J].电测与仪表,2022,59(06):12-1952.DOI:10.19753/j.issn1001-1390.2022.06.002. 1.问题背景 针对冷热电联供型微电网运行调度的优化问题&#xff0c;为实现节能减排的目…...

7、架构-架构的安全性

即使只限定在“软件架构设计”这个语境下&#xff0c;系统安全仍然是一 个很大的话题。我们谈论的计算机系统安全&#xff0c;不仅仅是指“防御系统 被黑客攻击”这样狭隘的安全&#xff0c;还至少应包括&#xff08;不限于&#xff09;以下这些问 题的具体解决方案。 认证&am…...

LeetCode题练习与总结:路径总和Ⅱ--113

一、题目描述 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], target…...

Java复数计算

复数在数学、科学或者工程领域是很常用的&#xff0c;可以通过调用Apache Commons Math库来完成&#xff0c;也可以自己手撸。 一、使用Apache Commons Math库 这个库有多个版本&#xff0c;在写这篇文章时&#xff0c;它的最新版是2022年12月19日的4.0-beta1&#xff0c;构建…...

MySQL-事务日志

事务的隔离性由 锁机制 实现 事务的原子性、一致性、隔离性 由事务的 redo日志 和 undo 日志来保证 redo log 称为 重做日志&#xff0c;提供再写入操作&#xff0c;恢复提交事务修改的页操作&#xff0c;用来保证事务的持久性。undo log 称为 回滚日志&#xff0c;回滚行记录…...

PySide6 GUI 学习笔记——常用类及控件使用方法(常用类坐标点QPoint)

控件是PySide设计好的能承载用户输入、输出的小窗体&#xff0c;将多个控件有机整合&#xff0c;能形成用户所需要的界面。而每一个控件&#xff0c;都有属于自己的属性、方法、信号、槽函数和事件&#xff08;event&#xff09;&#xff0c;且控件与控件之间又有继承关系。 G…...

算法练习——字符串

一确定字符串是否包含唯一字符 1.1涉及知识点 c的输入输出语法 cin>>s; cout<<"NO"; 如何定义字符串 切记&#xff1a;在[]中必须加数字——字符串最大长度&#xff0c;不然编译不通过 char s[101]; 如何获取字符串长度 char s[101];cin>>s;i…...

Flutter 中的 SliverOverlapInjector 小部件:全面指南

Flutter 中的 SliverOverlapInjector 小部件&#xff1a;全面指南 Flutter 是一个功能丰富的 UI 框架&#xff0c;由 Google 开发&#xff0c;允许开发者使用 Dart 语言构建跨平台的移动、Web 和桌面应用。在 Flutter 的滚动视图系统中&#xff0c;SliverOverlapInjector 是一…...

7个Python爬虫入门小案例

大家好&#xff0c;随着互联网的快速发展&#xff0c;数据成为了新时代的石油。Python作为一种高效、易学的编程语言&#xff0c;在数据采集领域有着广泛的应用。本文将详细讲解Python爬虫的原理、常用库以及实战案例&#xff0c;帮助读者掌握爬虫技能。 一、爬虫原理 爬虫&a…...

linux 利用 ~$() 构造数字

2024.6.1 题目 <?php //flag in 12.php error_reporting(0); if(isset($_GET[x])){$x $_GET[x];if(!preg_match("/[a-z0-9;|#\"%&\x09\x0a><.,?*\-\\[\]]/i", $x)){system("cat ".$x.".php");} }else{highlight_file(__F…...

七大获取免费https的方式

想要实现https访问最简单有效的的方法就是安装SSL证书。只要证书正常安装上以后&#xff0c;浏览器就不会出现网站不安全提示或者访问被拦截的情况。下面我来教大家怎么去获取免费的SSL证书&#xff0c;又如何安装证书实现https访问。 一、选择免费SSL证书提供商 有多家机构提…...

JVM(Java虚拟机)笔记

面试常见&#xff1a; 请你谈谈你对JVM的理解?java8虚拟机和之前的变化更新?什么是OOM&#xff0c;什么是栈溢出StackOverFlowError? 怎么分析?JVM的常用调优参数有哪些?内存快照如何抓取&#xff1f;怎么分析Dump文件&#xff1f;谈谈JVM中&#xff0c;类加载器你的认识…...

秒杀基本功能开发(显示商品列表和商品详情)

文章目录 1.数据库表设计1.商品表2.秒杀商品表3.修改一下秒杀时间为今天到明天 2.pojo和vo编写1.com/sxs/seckill/pojo/Goods.java2.com/sxs/seckill/pojo/SeckillGoods.java3.com/sxs/seckill/vo/GoodsVo.java 3.Mapper编写1.GoodsMapper.java2.GoodsMapper.xml3.分别编写Seck…...

centos 记录用户登陆ip和执行命令

centos 记录用户登陆ip和执行命令 在/etc/profile 文件末尾添加如下代码&#xff1a; #!/bin/bash USER_IPwho -u am i 2>/dev/null | awk {print $NF} | sed -e s/[()]//g HISTDIR/usr/share/.history if [ -z "$USER_IP" ]; then USER_IPhostname fi…...

JZ2440笔记:DM9000C网卡驱动

在厂家提供的dm9dev9000c.c上修改&#xff0c; 1、注释掉#ifdef MODULE #endif 2、用模块化函数修饰入口出口函数 3、在dm9000c_init入口函数&#xff0c;增加iobase (int)ioremap(0x20000000,1024);irq IRQ_EINT7; 4、一路进入&#xff0c;在dmfe_probe1中注释掉if((db…...

【数据结构】二叉树:简约和复杂的交织之美

专栏引入&#xff1a; 哈喽大家好&#xff0c;我是野生的编程萌新&#xff0c;首先感谢大家的观看。数据结构的学习者大多有这样的想法&#xff1a;数据结构很重要&#xff0c;一定要学好&#xff0c;但数据结构比较抽象&#xff0c;有些算法理解起来很困难&#xff0c;学的很累…...

信号稳定,性能卓越!德思特礁鲨系列MiMo天线正式发布!

作者介绍 礁鲨系列天线&#xff0c;以其独特的外观设计和强大的性能&#xff0c;成为德思特Panorama智能天线家族的最新成员。这款天线不仅稳定提供5G、WIFI和GNSS信号&#xff0c;更能在各类复杂环境中展现出卓越的性能。它的设计灵感来源于海洋中的礁鲨&#xff0c;象征着力量…...

编程学习技巧——实战

目录 学习思路待续、更新中 学习思路 实战大小项目 翻阅官网手册——学习技术,调试问题 待续、更新中 1 顿号、: 先使用ctrl. &#xff0c;再使用一遍切回 2 下标: 21 2~1~ 3 上标: 2 0 2^{0} 20 $2^{0}$ 4 竖线 | : &#124 ; | 5 空格: &emsp ; 6 换行: &nbs…...

GPU学习(1)

一、为什么要GPU 我们先看一个基本的神经网络计算 YF(x)AxB 这就是一次乘法一次加法 &#xff0c;也叫FMA&#xff0c;(fused multiply-add) 如果矩阵乘&#xff0c;就是上面的那个式子扩展一下&#xff0c;所以又用了这张老图 比如你要多执行好几个yAxB&#xff0c;可能比较简…...

TQSDRPI开发板教程:UDP收发测试

项目资源分享 链接&#xff1a;https://pan.baidu.com/s/1gWNSA9czrGwUYJXdeuOwgQ 提取码&#xff1a;tfo0 LWIP自环教程&#xff1a;https://blog.csdn.net/mcupro/article/details/139350727?spm1001.2014.3001.5501 在lwip自环的基础上修改代码实现UDP的收发测试。新建一…...

opencv进阶 ——(九)图像处理之人脸修复祛马赛克算法CodeFormer

算法简介 CodeFormer是一种基于AI技术深度学习的人脸复原模型&#xff0c;由南洋理工大学和商汤科技联合研究中心联合开发&#xff0c;它能够接收模糊或马赛克图像作为输入&#xff0c;并生成更清晰的原始图像。算法源码地址&#xff1a;https://github.com/sczhou/CodeFormer…...

虚拟机改IP地址

使用场景&#xff1a;当你从另一台电脑复制一个VMware虚拟机过来&#xff0c;就是遇到一个问题&#xff0c;虚拟的IP地址不一样&#xff08;比如&#xff0c;一个是192.168.1.3&#xff0c;另一个是192.168.2.4&#xff0c;由于‘1’和‘2’不同&#xff0c;不是同一网段&#…...

MySQL(二)-基础操作

一、约束 有时候&#xff0c;数据库中数据是有约束的&#xff0c;比如 性别列&#xff0c;你不能填一些奇奇怪怪的数据~ 如果靠人为的来对数据进行检索约束的话&#xff0c;肯定是不行的&#xff0c;人肯定会犯错~因此就需要让计算机对插入的数据进行约束要求&#xff01; 约…...

vue3学习使用笔记

1.学习参考资料 vue3菜鸟教程&#xff1a;https://www.runoob.com/vue3/vue3-tutorial.html 官方网站&#xff1a;https://cn.vuejs.org/ 中文文档: https://cn.vuejs.org/guide/introduction.html Webpack 入门教程&#xff1a;https://www.runoob.com/w3cnote/webpack-tutor…...

微信小程序怎么进行页面传参

微信小程序页面传参的方式有多种&#xff0c;每种方式都有其特定的使用场景和优势。以下是几种常见的页面传参方式&#xff0c;以及它们的具体使用方法和示例&#xff1a; URL参数传值 原理&#xff1a;通过在跳转链接中附加参数&#xff0c;在目标页面的onLoad函数中获取参数…...

隆道出席河南ClO社区十周年庆典,助推采购和供应链数字化发展

5月26日&#xff0c;“河南ClO社区十周年庆典”活动在郑州举办&#xff0c;北京隆道网络科技有限公司总裁助理姚锐出席本次活动&#xff0c;并发表主题演讲《数字化采购与供应链&#xff1a;隆道的探索与实践》&#xff0c;分享隆道公司在采购和供应链数字化转型方面的研究成果…...

NetApp财季报告亮点:全闪存阵列需求强劲,云计算收入增长放缓但AI领域前景乐观

在最新的财季报告中&#xff0c;NetApp的收入因全闪存阵列的强劲需求而显著增长。截至2024年4月26日的2024财年第四季度&#xff0c;NetApp的收入连续第三个季度上升&#xff0c;达到了16.7亿美元&#xff0c;较前一年同期增长6%&#xff0c;超出公司指导中值。净利润为2.91亿美…...

javascript读取本地目录

在JavaScript中&#xff0c;直接读取本地目录的能力受到浏览器安全限制&#xff0c;因为出于隐私和安全考虑&#xff0c;浏览器的JavaScript环境通常不允许直接访问用户的文件系统。然而&#xff0c;随着Web技术的发展&#xff0c;一些现代浏览器引入了File System API或Web Fi…...

Java基础八股

Java基础八股 Java语言Java语言有什么特点Java与C区别Java如何实现跨平台JVMvsJDKvsJRE标识符和关键字的区别是什么自增自减运算符移位运算符continue,break,return的区别是什么final,finally,finalize的区别final关键字的作用时什么 变量 Java语言 Java语言有什么特点 Java是…...

【机器学习300问】102、什么是混淆矩阵?

一、混淆矩阵的定义 混淆矩阵是一种用于评估分类模型性能的评估指标。当模型对数据进行预测并将数据分配到预定义的类别时&#xff0c;混淆矩阵提供了一种直观的方式来总结这些预测与数据实际类别之间的对应关系。具体来说&#xff0c;它是一个表格。 二、分类模型性能评估一级…...