LINUX基础 [三] - 进程创建
目录
前言
进程创建的初次了解(创建进程的原理)
什么是fork函数?
初识fork函数
写时拷贝
fork函数存在的意义
fork调用失败的原因
进程终止
运行完毕结果不正确
main函数返回
库函数函数exit
系统调用接口_exit
进程异常终止
进程等待
进程等待是什么
进程等待为什么要进行
进程等待怎么做
阻塞和非阻塞轮询
前言
上节我们已经讲了进程的概念了,大家应该对进程有感悟同时也有更深入的思考,上节课介绍了那么多进程,但是进程该怎么创建呢,今天就来给大家讲解一下 进程的创建
进程创建的初次了解(创建进程的原理)
创建新进程在Linux的下是由父进程来完成的,创建完成的新进程是子进程。
新进程的地址空间有两种可能性:
子进程是父进程的复制品(除了PID和task_struct是子进程自己的,其余的都从父进程复制而来)
子进程装入另一个程序。
在Linux下的fork函数用于创建一个新的进程,使用fork函数来创建一个进程时,子进程只是完全复制父进程的资源。这样得到的子进程和父进程是独立的,具有良好的并发性。但是进程间通信需要专门的机制。
什么是fork函数?
之前我们在Linux下启动一个进程的时候利用的是./可执行程序
,那是否有其他办法去启动一个进程呢?
初识fork函数
当然是有的,那就是使用fork()
这个函数。在使用之前呢我们要先去查看一下这个函数该如何使用------ 使用man 手册查询一下 fork 函数的使用
man 2 fork
- 可以看到,这个函数的功能就是去创建一个子进程,其返回值为
pid_t
- 注意:这里的 pid_t 类型 是无符号整数
函数说明:
-
通过复制调用进程创建一个新进程。
-
fork 有两个返回值。
-
父子进程代码共享,数据各自私有一份(采用写时拷贝)。
接下来,我们来测试一段代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // getpid, getppid, fork, sleep
#include <sys/types.h> // getpid, getppidint main()
{printf("before: I am a process\n");fork();printf("after: 创建一个新进程\n");return 0;
}
调用fork函数后,内核做了下面的工作:
1、创建了一个子进程的PCB结构体、并拷贝一份相同的进程地址空间和页表(PCB结构体中的一个指针指向该空间)
2、子进程和父进程起初共享代码和数据,并且页表中的虚拟地址和物理地址的映射关系是一样的,所以也指向相同的物理空间。
3、fork返回后将子进程添加到系统的进程列表中,由调度器调用(每个进程开始自己的旅程)
4、一旦其中任意一方尝试修改数据,那么就会发生写时拷贝,会开辟一块新的物理内存,然后改变页表的映射关系。
写时拷贝
通常,父子代码共享,父子再不写入时,数据也是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副本。
当父进程形成子进程之后,子进程写入,发生写时拷贝,重新申请空间,进行拷贝,修改页表(OS)
但是,我们怎么知道发生了写时拷贝呢?写时拷贝的内容都是由操作系统来完成的
其实父进程创建子进程的时候首先将自己的读写权限改成只读,然后再创建子进程。
此时是操作系统在做,用户并不知道,而且用户可能会对某一数据进行写入,这时页表转换就会出现问题,操作系统就会介入,就触发了我们重新申请内存拷贝内容的策略机制
fork函数存在的意义
fork函数常规用法:
1、一个父进程希望复制自己,使父子进程同时执行不同的代码段。例如,父进程等待客户端请求,生成子进程来处理请求。
2、一个进程要执行一个不同的程序。例如子进程从fork返回后,调用exec函数。 (进程替换
fork调用失败的原因
系统中有太多的进程
实际用户的进程数超过了限制
进程终止
问题引入:为什么main函数要返回0?返回多少的意义是什么???
成功只有一种情况,但是失败可以有无数的原因和理由!! 所以main函数的本质是进程运行时是否是正确的结果,如果不是,可以用不同的数字表示不同的出错原因!
进程退出场景:
- 代码运行完毕,结果正确
- 代码运行完毕,结果不正确
- 代码异常终止
运行完毕结果不正确
正常终止(可以通过 echo $? 查看进程退出码): $?->保存最后一次进程退出的退出码
1. 从main返回
2. 调用exit
3. _exit
main函数返回
进程中,谁会关心我的运行情况呢??——>父进程 !
我们之前写代码中,main函数只能return 0吗?
答案是肯定不是!
在多进程环境中,我们创建子进程的目的就是协助父进程办事,但是父进程怎么知道子进程把事情办得怎么样?所以父进程要知道子进程办的怎么样,就有了退出码,而main函数的返回值,就是进程的退出码!
其实main函数本质上也是一个被别人调用的函数,所以他return的结果其实是想告诉他的父进程自己的运行情况。
返回 0 就表示成功,其他数字就表示进程失败的原因,每个不同的数字代表不同的原因!
我们可以通过 strerror 函数来直接查看每个数字代表的意义
它可以返回描述错误码的字符串
#include<stdio.h>
#include<string.h>int main()
{for(int i = 0; i < 200; i++){printf("%d: %s\n", i, strerror(i));}return 0;
}
我们打印结果来看看
退出码 0 正好对应的是成功!
当我们134位置处时,发现已经没有错误信息了。
注意:错误码我们可以自己自定义!
main函数的退出码是可以被父进程获取的,用来判断子进程的运行结果
int main()
{return 31;
}
我们可以直接用 echo $? 指令查看进程的退出码:
我们可以发现指令:echo $? 返回的是上一个进程的错误码。当读取了一次之后,再读取就变成了0
库函数函数exit
exit和return的区别:return和exit在main函数里是等价的,因为exit表示退出进程,而main函数恰好执行完return也会退出进程,但是return在其他函数中代表的是函数返回。
系统调用接口_exit
#include void _exit(int status);参数:status 定义了进程的终止状态,父进程通过wait来获取该值
exit与_exit的区别
首先他们二者都可以让进程终止,并且使用方法也一样,那他们到底有什么区别呢?我们用代码来一探究竟!
//代码一:
int main()
{printf("Hello");exit(0);
}......
//代码二:
int main()
{printf("Hello");_exit(0);
}
为什么会出现这种情况呢?
printf打印如果不使用\n换行的话,数据会被存储到缓冲区里。exit函数会帮助我们刷新缓冲区的数据,然而_exit函数不会。因为exit函数在调用exit之前将所有缓存数据都写入了,所以在终止进程时,会将数据打印在屏幕上!
exit比_exit多做了一层最重要的工作就是刷新缓存,我们还可以得出另一个结论就是:缓冲区绝对不在内核区!!因为如果在内核区的话,系统调用的_exit在终止的时候也必然会把缓冲区刷新一下,因为现代操作系统不做任何浪费时间和空间的事情,所以肯定不是由内核维护缓存区,而是由用户区在维护!!(_exit压根看不到缓冲区,所以这个工作只能有exit去完成)
进程异常终止
用退出码可以告诉父进程自己的执行情况,那如果是异常中止了呢??那就连运行完毕这个条件都完成不了,更别谈结果是否正确了,所以我们可以知道异常必然是最先需要被知道的!因为一旦异常了,一般代码都没跑完,即使跑完了,错误码也不能让人相信,此时退出码就没有意义了!
举个例子:就好比我们平时考试一样,你考不好的时候大家会关心你为啥考不好,但如果你作弊了,性质就变了,即考得再好都让人觉得不可相信。
所以进程结束后应该优先判断该进程是否异常了,然后才能确定退出码能不能用!!
// 当我们在运行这样的代码时int a = 100;
a /= 0;
......
int *p = NULL;
*p = 100;
......
第一种情况: Floating point exception
第二种情况: Segmentation fault
当然不止这两个情况,但是它们都会让程序进程异常终止!
其实一旦程序出现了异常,操作系统就是通过 信号 的方式来杀掉这个进程!
而我们的前面两种情况正好对应了kill -8 和 kill -11
类似除0、野指针这样的错误,会触发一些硬件级别的错误,比如除0,cpu的状态寄存器会出现溢出的错误,而野指针,也就是们即将访问的虚拟地址在页表中找不到对应的映射,或者是建立的映射关系只有只读权限,反正最终会转化成一些硬件级别的信号来给操作系统。
所以,父进程需要关心子进程为什么异常,以及发生何种异常,系统会通过信号来告诉我们的进程发生了异常!!
while(1)
{printf("hello Linux, pid: %d\n", getpid());sleep(1);
}
所以我们最关键的是要看父进程是否收到了信号,如果没有收到就没有异常(具体如何收到,就涉及到进程等待的知识)
进程等待
进程等待是什么
首先在开始之前我们提个问题,到底什么是进程等待? - 是什么
进程等待的概念:
- 我们通常说的进程等待其实是通过wait/waitpid的方式,让父进程(一般)对子进程进行资源回收的等待过程,父进程必须等待这个子进程结束后,处理它的代码和数据!
进程等待为什么要进行
在了解完进程等待的概念后,新的问题出现了,我们为什么要进行进程等待?-为什么
- 在前面的文章中讲过,子进程退出,父进程如果不管不顾,就可能造成“僵尸进程”的问题,进而会造成内存泄露。
- 另外,进程一旦变成僵尸状态,那就刀枪不入,“杀人不眨眼”的 kill -9 指令也无能为力,因为谁也没有办法杀死一个已经死去的进程。
- 最后,父进程派给子进程的任务完成的如何,我们需要知道。如:子进程运行完成,结果对还是不对,或者是否正常退出。
- 父进程通过进程等待的方式,回收子进程资源,获取子进程的退出信息。
进程等待怎么做
我们进行了进程等待分析,发现进程等待非常的有必要。那么进程等待具体是怎么做的? - 如何做
父进程通过调用wait/waitpid方法来解决僵尸进程回收问题,以及获取子进程退出情况
wait方法
#include <sys/types.h>
#include <sys/wait.h>pid_t wait(int* status);
-
返回值:成功,返回被等待进程的 pid,失败返回-1。
-
参数:输出型参数,获取子进程的退出状态,不关心则可以设置成为 NULL。
waitpid方法
#include <sys/types.h>
#include <sys/wait.h>pid_t waitpid(pid_t pid, int* status, int options);
返回值:
- 当正常返回的时候 waitpid 返回等待到的子进程的进程 ID;
- 如果设置了选项 WNOHANG,而调用的过程中没有子进程退出,则返回0;
- 如果调用中出错,则返回-1,这时 errno 会被设置成相应的值以指示错误所在。
pid:
- pid = -1 表示等待任意一个子进程。与 wait 等效;
- pid > 0 表示等待进程 ID 与 pid 相等的子进程。
status:
- WIFEXITED(status):查看子进程是否正常退出。若为正常终止子进程返回的状态,则为真;WEXITSTATUS(status):查看进程的退出码。若非零,提取子进程的退出码。
options:
- 0:表示父进程以阻塞的方式等待子进程,即子进程如果处在其它状态,不处在僵尸状态(Z状态),父进程会变成 S 状态,操作系统会把父进程放到子进程 PCB 对象中维护的等待队列中,以阻塞的方式等待子进程变成僵尸状态,当子进程运行结束,操作系统会检测到,把父进程重新唤醒,然后回收子进程;
- WNOHANG:非阻塞轮询等待,若 pid 指定的子进程没有结束,处于其它状态,则 waitpid() 函数返回0,不予等待。若正常结束,则返回该子进程的 ID。
小Tips:wait 和 waitpid 都只能等待该进程的子进程,如果等待了其它的进程那么就会出错。
阻塞和非阻塞轮询
父进程只等待一个进程(阻塞式等待)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h> int main()
{ pid_t id = fork(); if(id < 0) { perror("fork"); return 1; } else if(id == 0) { // child int cnt = 5; while(cnt) { printf("I am child, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt--); sleep(1); } exit(0); } else { int cnt = 10; // parent while(cnt) { printf("I am parent, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt--); sleep(1); } int ret = wait(NULL); if(ret == id) { printf("wait success!\n"); } sleep(5); } return 0;
}
前五秒父子进程同时运行,紧接着子进程退出变成僵尸状态,五秒钟后父进程对子进程进行了等待,成功将子进程释放掉,最后再五秒钟后父进程也退出,整个程序执行结束。
父进程等待多个子进程(阻塞式等待)
一个 wait 只能等待任意一个子进程,因此父进程如果要等待多个子进程可以通过循环来多次调用 wait 实现等待多个子进程。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h> #define N 5
// 父进程等待多个子进程
void RunChild()
{ int cnt = 5; while(cnt--) { printf("I am child, pid:%d, ppid:%d\n", getpid(), getppid()); sleep(1); } return;
}
int main()
{ for(int i = 0; i < N; i++) { pid_t id = fork();// 创建一批子进程 if(id == 0) { // 子进程 RunChild(); exit(0); } // 父进程 printf("Creat process sucess:%d\n", id); } sleep(10); for(int i = 0; i < N; i++) { pid_t id = wait(NULL); if(id > 0) { printf("Wait process:%d, success!\n", id); } } sleep(5); return 0;
}
如果子进程不退出,父进程在执行 wait
系统调用的时候也不返回(默认情况),默认叫做阻塞状态。由此可以看出,一个进程不仅可以等待硬件资源,也可以等待软件资源,这里的子进程就是软件。
获取子进程的退出信息(阻塞式等待)
相关文章:
LINUX基础 [三] - 进程创建
目录 前言 进程创建的初次了解(创建进程的原理) 什么是fork函数? 初识fork函数 写时拷贝 fork函数存在的意义 fork调用失败的原因 进程终止 运行完毕结果不正确 main函数返回 库函数函数exit 系统调用接口_exit 进程异常终止 进…...
AI比人脑更强,因为被植入思维模型【24】替身决策思维模型
定义 替身决策思维模型是一种在面对复杂问题或决策情境时,通过将自己代入到不同的角色(即“替身”)中,从这些角色的视角出发去思考、分析和做出决策的思维方式。这种思维模型要求决策者暂时摆脱自身固有的思维定式和立场…...
数据清洗:基于python抽取jsonl文件数据字段
基于python抽取目录下所有“jsonl”格式文件。遍历文件内某个字段进行抽取并合并。 import os import json import time from tqdm import tqdm # 需要先安装:pip install tqdmdef process_files():# 设置目录路径dir_path r"D:\daku\关键词识别\1623-00000…...
spring后端处理各种请求
在Spring MVC中处理JSON请求和返回JSON消息的步骤如下: 1. 添加依赖 确保项目中包含处理JSON的库,如Jackson。 Maven配置(pom.xml): <dependency><groupId>com.fasterxml.jackson.core</groupId>…...
企业级部署zabbix分布式监控系统
目录 一、Zabbix分布式监控系统介绍 1.什么是“Zabbix” 2.Zabbix分布式监控系统的特点 3.Zabbix分布式监控系统的原理 4.Zabbix分布式监控系统的运用 5. Zabbix分布式监控系统的部署顺序 二、搭建 1.设备硬件配置参考 2.zabbix分布式监控系统各节点设备名称和IP规划 …...
OkHttp 的证书设置
在 Android 开发中,通过 OkHttp 自定义 SSLSocketFactory 和 X509TrustManager 可以有效增强 HTTPS 通信的安全性,防止中间人攻击(如抓包工具 Charles/Fiddler 的拦截)。以下是实现防抓包的关键技术方案: 一、Okhttp设…...
ETL:数据清洗、规范化和聚合的重要性
在当今这个数据呈爆炸式增长的时代,数据已成为企业最为宝贵的资产之一。然而,数据的海量增长也伴随着诸多问题,如数据来源多样、结构复杂以及质量问题等,这些问题严重阻碍了数据的有效处理与深度分析。在此背景下,ETL&…...
蓝桥杯备考:图的遍历
这道题乍一看好像没什么不对的,但是!但是!结点最大可以到10的5次方!!!我们递归的时间复杂度是很高的,我们正常遍历是肯定通过不了的,不信的话我们试一下 #include <iostream>…...
【多媒体交互】Unity Kinect实现UI控件的点击
在Unity中,通过Kinect实现UI控件的点击功能,主要涉及手部追踪、坐标映射和手势检测三个核心环节。 实现步骤 初始化Kinect与关节追踪 使用KinectManager获取用户ID和手部关节点(如JointType.HandLeft)的坐标。 long userId _…...
QinQ项展 VLAN 空间
随着以太网技术在网络中的大量部署,利用 VLAN 对用户进行隔离和标识受到很大限制。因为 IEEE802.1Q 中定义的 VLAN Tag 域只有 12 个比特,仅能表示 4096 个 VLAN,无法满足城域以太网中标识大量用户的需求,于是 QinQ 技术应运而生。…...
OBS虚拟背景深度解析:无需绿幕也能打造专业教学视频(附插件对比)
想要录制教学视频却苦于背景杂乱?本文将手把手教你用OBS实现专业级虚拟背景效果,无需绿幕也能轻松营造沉浸式教学场景。文末附6个提升画面质感的免费背景资源! 一、虚拟背景的核心价值:从「教师宿舍」到「虚拟讲堂」的蜕变 我们调…...
26考研——图(6)
408答疑 文章目录 一、图的基本概念二、图的存储三、图的遍历四、图的应用五、图的代码实操六、参考资料鲍鱼科技课件26王道考研书 七、总结图的存储结构邻接矩阵邻接表 图的遍历图的相关概念完全图和连通图图的连通性 关键路径学习建议 一、图的基本概念 文章链接: link 二、…...
Redis常用数据类型深度解析:从理论到最佳实践
Redis常用数据类型深度解析:从理论到最佳实践 一、引言二、Redis数据类型全景图三、核心数据类型详解**1. String(字符串)****2. Hash(哈希表)****3. List(列表)****4. Set(集合&…...
DeepSeek-V3 模型更新,加量不加价
DeepSeek V3-0324 是 DeepSeek V3 系列的重要升级版本,虽然被官方称为「小版本迭代」,但其在技术能力、开源策略和用户体验上均有显著提升。以下是主要新特性功能和核心变化: 推理能力 基准测试性能显著提升: MMLU-Pro࿱…...
Vue项目的 Sass 全局基础样式格式化方案,包含常见元素的样式重置
步骤 1:创建全局样式文件 在项目中创建文件:src/assets/scss/global.scss 内容如下: // 全局盒模型设定(边框计入宽高) *, *::before, *::after {box-sizing: border-box;margin: 0;padding: 0; }// 基础元素样式重置…...
【Spring篇】Spring的生命周期
一、Bean 生命周期的核心阶段 1. 实例化(Instantiation) • 触发时机:容器启动时(单例 Bean)或请求时(原型 Bean)。 • 实现方式: 通过反射(Class.newInstance() 或构造…...
Qt中通过QLabel实时显示图像
Qt中的QLabel控件用于显示文本或图像,不提供用户交互功能。以下测试代码用于从内置摄像头获取图像并实时显示: Widgets_Test.h: class Widgets_Test : public QMainWindow {Q_OBJECTpublic:Widgets_Test(QWidget *parent nullptr);~Widgets…...
[数据结构]1.时间复杂度和空间复杂度
这里写目录标题 1. 算法复杂度2. 时间复杂度2.1 执行次数2.2 大O渐进表示法2.3 常见时间复杂度计算eg1eg2eg3eg4eg5eg6eg7eg8eg9 3. 空间复杂度eg1eg2eg3eg4 4. 常见复杂度对比5. 复杂度练习eg1 1. 算法复杂度 衡量一个算法的好坏,一般是从时间空间两个维度来衡量&…...
【每日算法】Day 6-1:哈希表从入门到实战——高频算法题(C++实现)
摘要 :掌握高频数据结构!今日深入解析哈希表的核心原理与设计实现,结合冲突解决策略与大厂高频真题,彻底掌握O(1)时间复杂度的数据访问技术。 一、哈希表核心思想 哈希表(Hash Table) 是一种基于键值对的…...
物联网平台架构介绍
物联网是连接物理设备、传感器、软件等的网络系统,使设备能够自动收集、交换和处理数据,实现智能化识别、定位、跟踪、监控和管理。随着物联网技术的飞速发展,物联网平台架构的设计变得至关重要,它决定了物联网系统的性能、可扩展…...
TCP/IP三次握手的过程,为什么要3次?
一:过程 第一次(SYN): 客户端发送一个带有SYN标志的TCP报文段给服务器,设置SYN1,并携带初始序列号Seqx(随机值),进入SYN_SENT状态。等待服务器相应。 第二次(…...
开源模型应用落地-语音转文本-whisper模型-AIGC应用探索(四)
一、前言 语音转文本技术具有重要价值。它能提高信息记录和处理的效率,使人们可以快速将语音内容转换为可编辑、可存储的文本形式,方便后续查阅和分析。在教育领域,可帮助学生更好地记录课堂重点;在办公场景中,能简化会议记录工作。同时,该技术也为残障人士提供了便利,让…...
Qt开发:QInputDialog的使用
文章目录 一、QInputDialog的介绍二、 QInputDialog的基本用法三、使用 QInputDialog的实例四、QInputDialog的信号与槽 一、QInputDialog的介绍 QInputDialog 是 Qt 提供的一个对话框类,用于获取用户输入的文本、整数或浮点数。它提供了简单易用的静态方法和可定制…...
【系统架构设计师】软件质量管理
目录 1. 说明2. 软件质量保证2.1 说明2.2 质量保证的主要目标2.3 目标2.4 主要作用2.5 主要任务 3. 软件质量保证3.1 说明3.2 ISO 90003.3 CMM 4. 例题4.1 例题1 1. 说明 1.软件质量就是软件与明确地和隐含地定义的需求相一致的程度,更具体地说,软件质量…...
医院挂号预约小程序|基于微信小程序的医院挂号预约系统设计与实现(源码+数据库+文档)
医院挂号预约小程序 目录 基于微信小程序的医院挂号预约系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、小程序用户端 2、系统服务端 (1) 用户管理 (2)医院管理 (3)医生管理 …...
UE4-UE5虚幻引擎,前置学习一--Console日志输出经常崩溃,有什么好的解决办法
有些差异 这么牛逼的引擎,居然有这种入门级别的问题,一触发清理,大概率(80%)会崩溃 无论虚幻5还是UE4都有这个问题,挺烦人的 实在忍不了了,这次,今天 就想问问有什么好的处理方法么?&#x…...
javaSE.多维数组
1 final 引用类型 final int[] arr 继承Object 的引用类型,不能改变引用的对象 存的其实是引用 数组类型数组,其实存的是引用 int [][] arr new int[][] { {1,2,3}, {4,5,6} };int [] a arr[0]; int [] b arr[1];...
Linux输入系统应用编程
什么是输入系统 Linux 输入系统是处理用户输入设备(如键盘、鼠标、触摸屏、游戏手柄等)的软件架构。在应用编程层面,它提供了与这些输入设备交互的接口。 主要组成部分 输入设备驱动层:直接与硬件交互的驱动程序 输入核心层:内核中的输入子…...
leetcode11.盛水最多的容器
双指针问题,指向前后边界,每次只移动高度较小的那个 class Solution { public:int maxArea(vector<int>& height) {int leftIndex0,rightIndexheight.size()-1;int result0;while(leftIndex<rightIndex){resultmax(result,(rightIndex-lef…...
ngx_http_index_loc_conf_t
定义在 src\http\modules\ngx_http_index_module.c typedef struct {ngx_array_t *indices; /* array of ngx_http_index_t */size_t max_index_len; } ngx_http_index_loc_conf_t; ngx_http_index_loc_conf_t 是 Nginx 中用于管理 index 指…...
[C++面试] 你了解视图吗?
一、入门 1、什么是 C 视图(View)?请简要说明其概念和用途 它提供了对序列(如数组、容器等)的非拥有性、只读或可写的访问。(就像是个透明的放大镜,它能让你去看一组数据,但它自己…...
NetMizer-日志管理系统-远程命令执行漏洞挖掘
漏洞描述:NetMizer 日志管理系统 cmd.php中存在远程命令执行漏洞,攻击者通过传入 cmd参数即可命令执行 1.fofa搜素语句 title"NetMizer 日志管理系统" 2.漏洞验证 网站页面 验证POC /data/manage/cmd.php?cmdid...
UDP通信实现
一、Socket简介(套接字) TCP/IP 五层网络模型的应用层编程接口称为Socket API, Socket( 套接字 ) ,它是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。 一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换…...
Browserlist 使用指南:应对浏览器兼容性问题的解决方案
前言 在前端开发中,我们经常需要处理各种不同的浏览器兼容性问题。每个浏览器的版本众多,处理这些问题可能会让人感到头疼。幸运的是,有一个名为 Browserlist 的工具可以大大简化这项工作。本文将介绍 Browserlist 的作用和使用方法…...
[蓝桥杯 2023 省 A] 异或和之和
题目来自洛谷网站: 暴力思路: 先进性预处理,找到每个点位置的前缀异或和,在枚举区间。 暴力代码: #include<bits/stdc.h> #define int long long using namespace std; const int N 1e520;int n; int arr[N…...
ABC391题解
A 算法标签: 模拟 #include <iostream> #include <algorithm> #include <cstring> #include <map>using namespace std;const int N 8; map<string, string> mp;int main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);mp.insert({…...
React - LineChart组件编写(用于查看每日流水图表)
一、简单版本 LineChart.tsx // src/component/LineChart/LineChart.tsx import React, {useEffect,useRef,useImperativeHandle,forwardRef,useMemo,useCallback, } from react; import * as echarts from echarts/core; import type { ComposeOption } from echarts/core; …...
什么情况下需要使用二级指针
当你需要一个函数修改另一个函数中的指针变量时(改变指针变量的指向),你必须传递该指针的地址,也就是"指向指针的指针"。这是C语言中实现"引用传递"效果的标准方式。 函数A中声明了一个结构体指针变量mys&am…...
动态规划(8.下降路径最小和(medium))
题目链接:931. 下降路径最小和 - 力扣(LeetCode) 解法: 关于这⼀类题,由于我们做过类似的,因此「状态表示」以及「状态转移」是比较容易分析出来的。 比较难的地方可能就是对于「边界条件」的处理。 1. 状…...
自动插入分号机制
📜 JS 自动分号插入(ASI)机制详解 自动分号插入(Automatic Semicolon Insertion)是 JavaScript 中一个独特而重要的特性,它影响着代码的解析和执行方式。 🌟 核心概念速览 ASI 引擎自动补充分号 当 JavaScript 解析器遇到特定语法情况时&a…...
C语言贪吃蛇实现
When the night gets dark,remember that the Sun is also a star. 当夜幕降临时,请记住太阳也是一颗星星。 ————《去月球海滩篇》 目录 文章目录 一、《贪吃蛇》游戏介绍 二、WIN32部分接口简单介绍 2.1 控制台窗口大小设置 2.2 命令行窗口的名称的变更 2…...
基于数据挖掘的网络入侵检测关键技术研究
标题:基于数据挖掘的网络入侵检测关键技术研究 内容:1.摘要 随着互联网的迅速发展,网络安全问题日益严峻,网络入侵行为对个人、企业和国家的信息安全构成了巨大威胁。本文的目的是研究基于数据挖掘的网络入侵检测关键技术,以提高网络入侵检测…...
git上传大文件到远程仓库中
git 上传大文件报错 上传大文件文件到远程仓库上面,出现错误(gitee-100M,github-50M) remote: error: File: f422c55c723a183a1944cbec840c0171042c8251 135 MB, exceeds 100.00 MB. 意思是单个文件超过100M导致上传失败。 安装LFS curl…...
计算机网络基础之三种交换技术及其性能分析
一. 交换技术基础 1. 三种交换技术 电路交换:用于电话网络报文交换:用于电报网络分组交换:用于现代计算机网络 2. 人类历史上的通信网络 #mermaid-svg-AeGvrkUbCkicFOIo {font-family:"trebuchet ms",verdana,arial,sans-serif;…...
ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots
ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots 研究动机解决方案技术路线感知模块运动模块导航模块补充 实验结果 ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots 研究动机 行走控制器不能依赖于稳定和周期性的步态,而必…...
【AI学习笔记】AI造神时代的潘式理论与智能进化
背景前摇: 周会分享选题,决定选择这篇华为蓝军部长潘少钦先生所著的文章,原题目为《AI如此强大,我是否要改行?》。选择这篇文章的理由是,其不仅有充实扎实的AI基础知识作为铺垫,更具有独特鲜明…...
CVE-2021-45232未授权接口练习笔记
CVE-2021-45232 是 Apache APISIX Dashboard 中的一个严重权限漏洞,类似于攻击者无需密码即可拿到整个网关系统的“万能钥匙”。攻击者利用此漏洞,可直接操控网关流量转发规则,甚至远程执行代码,引发服务器沦陷。 默认账户密码导致…...
远场分量(平面波角谱)与倏逝波
远场分量(平面波角谱)与倏逝波的详细解释 在光学和电磁学中,远场分量(平面波角谱)和倏逝波是描述光场传播特性的两个核心概念,尤其在衍射理论、近场光学和超分辨成像中至关重要。以下是它们的物理意义、数…...
修改Flutter工程中Android项目minSdkVersion配置
Flutter项目开发过程中,根据模板自动生成.android项目,其中app>build.gradle中minSdkVersion的值是19,但是依赖了一个三方库,它的Android sdk 最小版本只支持到21,运行报错如下: 我们可以手动修改.andro…...
后端返回了 xlsx 文件流,前端怎么下载处理
当后端返回一个 .xlsx 文件流时,前端可以通过 JavaScript 处理这个文件流并触发浏览器下载。 实现步骤 发送请求获取文件流: 使用 fetch 或 axios 等工具向后端发送请求,确保响应类型设置为 blob(二进制数据流)。 创建…...