Linux(十三)fork + exec进程创建
一、进程创建
在了解进程创建的步骤前,让我们先通过实例观察一下。大家可以跟小编一起,在终端中执行3次ps -f命令,观察一下。
通过上图,我们可以发现,3次ps -f的父进程(PPID)都是一样的(图上为3520),又可以发现这个PPID和bash的PID是一样的;那我们得出结论;执行了3次ps -f,ps -f的父进程的ID都是一样的,即是bash。
实际上,Linux上这个bash就是不断的复制自身,然后把复制出来的用exec替换成想要执行的程序(比如ps);运行ps,发现ps是bash的一个子进程;原因就是bash把自己复制一份,然后替换成ps;
在这里,就会用到我们之前学习的写时拷贝技术了。那我们回顾一下写时拷贝技术的定义“就是fork的时候,子进程直接把父进程的页表复制过来,子进程发生写入(修改)的时候才分配内存复制,然后进行相应的页表修改”。
在替换这步就体现了写时拷贝的意义,如果全部都要替换,那么最开始的复制是没有意义的;注意,用了写时拷贝就只复制了几个页表的映射,内容还没有复制,然后执行了替换exec。(即下图)
通过上面的观察和推导,我们就可以了解到在Linux新的进程的产生过程(也就是进程创建)
- fork:复制进程
- exec 系列: 将当前进程替换成另外一个进程
二、进程替换exec系列介绍
小编之前一直在和大家强调一定要学会使用帮助手册,现在就是大家可以查看帮助手册的时候啦!因为我们要学习一个新的知识啦!
man exec
我们可以发现,使用exec需要添加相应的头文件,且exec是一个系列,里面包含了6种库函数,在这里呢,小编只和大家学习前5个,因为最后一个execvpe不通用。大家也可以通过小编在图片上的标注,了解每个库函数的使用方法。
1、execl
我们通过代码来演示一下吧。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main()
{printf("main pid =%d\n",getpid());execl("/usr/bin/ps","ps","-f",(char*)0);printf("hello!\n");printf("execl error!\n");exit(0);
}
在这里,我们要注意,原来的程序替换成了ps程序,但PCB没有改变,但是PCB里面的有些值被修改了,比如PCB中程序的名字换成了新的名字。(./main -> ps -f)
那大家和小编一起思考几个问题;
(1)新的进程从哪里执行?
新的进程从主函数的第一行开始执行,也就是ps程序的主函数的第一行代码开始执行,这
个和fork方法不一样,fork返回以后,从fork所在位置开始执行;所以可以直接在execl下面打印一个失败,如果成功就根本不会执行到这里;
所以,在上面的代码中就有了这两句
printf("hello!\n");
printf("execl error!\n");
(2)如果将execl里面的第二个参数改为"xxxy",程序还能否执行?
execl("/usr/bin/ps","ps","-f",(char*)0);
改为execl("/usr/bin/ps","xxxy","-f",(char*)0);
通过运行截图,我们可以发现可以正常运行,只是程序命令改为了xxxy
(3)如果将execl里面的第一个参数改为"xxxy",程序还能否执行?
execl("/usr/bin/ps","ps","-f",(char*)0);
改为execl("/usr/bin/xxxy","ps","-f",(char*)0);
我们通过运行截图可以发现,execl是没有成功执行的,因为打印了接下来的错误提示。
通过(2)(3),我们就知道只要execl第一个参数不出错,第一个参数如果出错了,你就找不到这个程序了;那么就运行不成功了;
(4)去掉\n,会发生什么?
printf("main pid =%d\n",getpid());
改为 printf("main pid =%d",getpid());
(5)ps也是由ps.c编译为ps可执行程序的,同理cp也是;
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main()
{printf("main pid =%d\n",getpid());execl("/usr/bin/cp","cp","yma.c","ymb.c",(char*)0);printf("execl error!\n");exit(0);
}
注意:在这里实现cp命令上的时候,大家可能会发现,直接执行./mian是 运行不成功的。这是因为在代码里我们要将yma.c的内容复制到ymb.c里面,但在我们当前路径下是还没有创建yma.c的。
这也就是为什么在成功运行的截图里,小编会先使用cat > yma.c创建一个yma.c文件。
2、execlp
只给文件名,不需要给文件路径,因为它可以去环境变量PATH所指的位置去搜索;
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main()
{printf("main pid =%d\n",getpid());//execl("/usr/bin/ps","ps","-f",(char*)0);execlp("ps","ps","-f",(char*)0);printf("hello!\n");printf("execlp error!\n");exit(0);
}
注意,第一句,虽然有两个ps,但是不能省,第一个代表我们启动的是ps(去环境变量下搜
索),第二个代表的是替换的程序也就是新程序的名字;
3、execle
和execl参数一样,只是多了最后一个环境变量;
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main(int argc,char *argv[],char*envp[])
{printf("main pid =%d\n",getpid());//execl("/usr/bin/ps","ps","-f",(char*)0);//execlp("ps","ps","-f",(char*)0);execle("/usr/bin/ps","ps","-f",(char*)0,envp);printf("hello!\n");printf("execle error!\n");exit(0);
}
4、execv
execv是把参数都放在了一个数组中,然后把这个数组传递进去即可;
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main(int argc,char *argv[],char*envp[])
{printf("main pid =%d\n",getpid());//execl("/usr/bin/ps","ps","-f",(char*)0);//execlp("ps","ps","-f",(char*)0);//execle("/usr/bin/ps","ps","-f",(char*)0,envp);char *myargv[]={"ps","-f",0};execv("/usr/bin/ps",myargv);printf("hello!\n");printf("execv error!\n");exit(0);
}
5、execvp
第一个参数只要文件名,不要路径;
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main(int argc,char *argv[],char*envp[])
{printf("main pid =%d\n",getpid());//execl("/usr/bin/ps","ps","-f",(char*)0);//execlp("ps","ps","-f",(char*)0);//execle("/usr/bin/ps","ps","-f",(char*)0,envp);char *myargv[]={"ps","-f",0};//execv("/usr/bin/ps",myargv);execvp("ps",myargv);printf("hello!\n");printf("execvp error!\n");exit(0);
}
6、execve(重点)
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main(int argc,char *argv[],char*envp[])
{printf("main pid =%d\n",getpid());//execl("/usr/bin/ps","ps","-f",(char*)0);//execlp("ps","ps","-f",(char*)0);//execle("/usr/bin/ps","ps","-f",(char*)0,envp);char *myargv[]={"ps","-f",0};//execv("/usr/bin/ps",myargv);//execvp("ps",myargv);execve("/usr/bin/ps",myargv,envp);printf("hello!\n");printf("execve error!\n");exit(0);
}
7、总结
助记:
l(list) 参数地址列表,以空指针结尾
v(vector) 存放各个参数地址的指针数组的地址
p(path) 按PATH环境变量指定的目录搜索可执行文件
e(enviroment) 存放环境变量字符地址的指针数组的地址
//pathname:新替换的程序的路径 + 名字
//arg:传给新程序主函数的第一个参数,一般为程序的名字
//arg后面是剩余参数列表,参数个数可变,必须以空指针作为最后一个参数 (exec系列中包含l 的,eg:execl,execlp,execle)
int execl(const char* pathname, const char * arg, ...,(char *)0);
int execlp(const char* file, const char * arg, ...,(char *)0);
int execle(const char* pathname, const char * arg, ... ,(char *)0,char* const envp[ ]);
int execv(const char * pathname, char* const argv[ ]);
int execvp(const char * file, char* const argv[ ]);
int execve(const char * pathname, char* const argv[ ], char* const envp[ ]);//前五个是库函数,最后一个是系统调用,所以本质上上面5个都是通过第6个系统调用实现的
也就是说,上面5个都是调用的execve,不过都是把参数放进数组,然后把数组传递给这个系统调用execve;也就是说,这些方法没有本质区别;也就是说,本质上只有一个替换方法,就是execve;注意,(char *)0写成(char*)NULL也是可以的;
三、进程替换的应用
写一个程序main.c,运行起来之后替换执行test程序(test打印参数内容)
//main.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main(int argc,char *argv[],char*envp[])
{printf("main start and mainpid = %d\n",getpid());execl("./test","./test","a","b","c",(char*)0);perror("execl error!\n");printf("main end!\n");exit(0);
}
//test.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main(int argc,char *argv[],char*envp[])
{printf("test start and test_pid = %d\n",getpid());for(int i=0;i<argc;i++){ printf("argv[%d]=%s\n",i,argv[i]);} printf("test end!\n");exit(0);
}
四、进程创建示例
1、创建ps命令——execl的使用(结合fork 1)
exec系列单独是能使用的,但是没有多大意义.通常我们会结合fork一起使用;
fork+exec()是Linux上创建新进程的方式;
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<wait.h>int main()
{printf("main pid = %d,ppid = %d\n",getpid(),getppid());pid_t pid=fork();assert(pid!=1);if(pid==0){printf("child pid = %d,ppid = %d\n",getpid(),getppid());execl("/usr/bin/ps","ps","-f",NULL);printf("execl error!");exit(0);} else{ wait(NULL);} exit(0);
}
2、fork和exec联合使用创建一个全新的进程(结合fork 2)
当前主程序main通过fork复制产生一个子进程,子进程用新程序"newmain"替换自身;(newmain:打印参数内容和环境变量)
//main.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<wait.h>int main(int argc,char *argv[],char*envp[])
{printf("main pid = %d\n",getpid());pid_t pid=fork();assert(pid!=1);if(pid==0){char *myargv[]={"newmain","hello","abc","123",(char*)0};//创建自己的环境变量//char *myenvp[]={"MYSTR=hello","VAL=100",(char*)0};execve("./newmain",myargv,envp);//execve("./newmain",myargv,myenvp);perror("execl error!");exit(0);} wait(NULL);printf("main over\n");exit(0);
}
//newmain.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main(int argc,char *argv[],char *envp[])
{printf("newmain pid = %d\n",getpid());int i=0;printf("argc=%d\n",argc);for(;i<argc;i++){printf("argv[%d]=%s\n",i,argv[i]);} for(i=0;envp[i]!=NULL;i++){printf("envp[%d]=%s\n",i,envp[i]);} exit(0);
}
运行结果截图
【小编有话说】
本次内容就要结束啦,今天主要是和小伙伴们一起学习了进程的创建以及exec系列替换函数,大家一定要自己练习一下昂!!!
最后还是老三样,点赞收藏和关注~
喜欢小编的文章就不要忘记这三样,点赞收藏加关注,找到小编不迷路~
相关文章:
Linux(十三)fork + exec进程创建
一、进程创建 在了解进程创建的步骤前,让我们先通过实例观察一下。大家可以跟小编一起,在终端中执行3次ps -f命令,观察一下。 通过上图,我们可以发现,3次ps -f的父进程(PPID)都是一样的…...
集合计算高级函数
说明 过滤 遍历一个集合并从中获取满足指定条件的元素组成一个新的集合转化/映射(map)将集合中的每一个元素映射到某一个函数扁平化 扁平化映射 注:flatMap 相当于先进行 map 操作,在进行 flatten 操作集合中的每个元素的子元素映…...
鼎讯信通 便携式雷达信号干扰模拟器:打造实战化电磁环境的新利器
在现代战争中,电磁环境的复杂性直接影响着雷达装备的性能和作战效果。面对敌方日益精进的电子战手段,如何提升雷达设备的抗干扰能力,确保其在实战环境中的稳定性和可靠性,已成为各国军队和科研机构的重要课题。 为此,…...
避开养生误区,拥抱健康生活
在追求健康的道路上,我们常常会陷入一些养生误区,不仅无法达到预期效果,还可能损害身体健康。只有拨云见日,认清这些误区,采取正确的养生方式,才能真正拥抱健康生活。 很多人认为,保健品吃得…...
解码ChatBI技术形态:独立对话框、插件式与IM集成模式的技术优劣
ChatBI的形态之争 随着大语言模型(LLM)技术的成熟,**对话式商业智能(ChatBI)**正成为企业数据分析的新范式。然而,不同的技术形态直接影响ChatBI的落地效果——独立对话框、插件式助手、IM集成机器人&…...
rockylinux 8 9 升级到指定版本
rockylinux 8 update 指定版本 rockylinux 历史版 所有版本rockylinux 最新版 所有版本vault历史版 pub最新版(https://dl.rockylinux.org)地址后面增加不同名称 echo "delete repos" rm -rf /etc/yum.repos.d/*echo "new rockylinux repo" cat <<EO…...
一文详解OpenCV环境搭建:Ubuntu20.4使用CLion配置OpenCV开发环境
在计算机视觉和图像处理领域,OpenCV 是一个不可或缺的工具。其为开发者提供了一系列广泛的算法和实用工具,支持多种编程语言,并且可以在多个平台上运行。对于希望在其项目中集成先进视觉功能的开发者来说,掌握如何配置和使用OpenC…...
Android Coli 3 ImageView load two suit Bitmap thumb and formal,Kotlin(四)
Android Coli 3 ImageView load two suit Bitmap thumb and formal,Kotlin(四) 对 Android Coli 3 ImageView load two suit Bitmap thumb and formal,Kotlin(三)-CSDN博客 进行完善,注意完善 …...
01-JVM 内存模型与 GC 原理
JVM 内存模型与 GC 原理解析 本文将从 JVM 内存模型入手,深入剖析各个区域的作用、GC 的运行机制与常见算法,并结合源码与面试思维,带你掌握 JVM 的底层世界。 一、JVM 内存模型(Java Memory Model) JVM 将内存划分为…...
Docker--Docker镜像制作的注意事项
Docker 镜像制作 dockerfiles的指令讲解 链接 CMD和ENTRYPOINT CMD 和 ENTRYPOINT 是 Dockerfile 中用于指定容器启动时运行命令的两个指令。它们在功能上有一些相似之处,但也存在重要区别。 在编辑Dockerfile时,ENTRYPOINT或者CMD命令会自动覆盖之前…...
AI:支持向量机(SVM)
支持向量机(SVM)理论基础详解:从零开始的完全指南 一、SVM的核心思想:直观理解 1.1 什么是分类问题? 想象你在玩一个游戏:桌上有红色和蓝色的球,你需要画一条线把它们分开。这条线就是分类边界。SVM的目标是找到一条最优分界线,使得这条线到最近的红色球和蓝色球的距…...
Vue.js 中 v-if 的使用及其原理
在 Vue.js 的开发过程中,条件渲染是一项极为常见的需求。v-if指令作为 Vue.js 实现条件渲染的关键手段,能够根据表达式的真假来决定是否渲染某一块 DOM 元素。它在优化页面展示逻辑、提升用户体验等方面发挥着重要作用。接下来,我们就深入探讨…...
Vue.js 中 v-show 的使用及其原理
在 Vue.js 的开发过程中,我们常常需要根据不同的条件来控制页面元素的显示与隐藏。v-show指令作为 Vue.js 提供的重要工具之一,为我们实现这一功能提供了便捷的途径。它与v-if指令有些相似,但在使用方法和原理上存在着明显的区别。接下来&…...
docker安装redisSearch
1.背景 Redis Search 是 Redis 官方提供的全文搜索引擎,它为Redis 提供全文搜索、索引和复杂查询功能。它基于内存存储,结合了 Redis 的高性能和倒排索引技术,支持实时搜索、聚合分析、模糊匹配等场景。RedisSearch 适用于需要快速检索结构化或非结构化…...
ADI的BF561双核DSP怎么做开发,我来说一说(六)IDE硬盘设计
作者的话 ADI的双核DSP,最早的一颗是Blackfin系列的BF561,这颗DSP我用了很久,比较熟悉,且写过一些给新手的教程。 是的你没有看错,就是IDE,那个最老的硬盘,我们当年做过此类设计。 硬件准备 …...
5.数据结构-图
5.数据结构-图 5.1 图的定义和基本术语5.1.1 图的定义5.1.2 图的基本术语 5.2图的存储结构5.2.1邻接矩阵采用邻接矩阵表示法创建无向网邻接表 5.1 图的定义和基本术语 5.1.1 图的定义 图 G由两个集合V和E组成,记为 G ( V , E ) G(V,E) G(V,E),其中V是…...
uni-app使用web-view传参的坑
问题描述 uni-app开发的一个页面,需要点击时跳转到PC端后台的一个详情页,所以需要传参如下: ticketIdticketCodetoken(用于自动登录,校验身份的) 但是吧,如果你明文传token,容易导…...
Android studio打包uniapp插件
一.参考资料与环境准备 原生工程配置需要使用到Android studio和HbuilderX 当前测试的as版本-20240301,下载地址:HbuilderX版本:4.36 二.插件创建流程 1.导入下载的UniPlugin-Hello-AS工程(下载地址见参考资料) 2.生成jks证书…...
SVT-AV1学习-函数selfguided_restoration_fast_internal
一 selfguided_restoration_fast_internal 函数作用 selfguided_restoration_fast_internal是SVT-AV1 编码器中用于自引导恢复Guided Resration SGR 的一个内部函数,通过自引导滤波技术对输入的去燥他图像数据进行处理,生成一个去燥版本的图像࿰…...
双引擎驱动:解密音视频体验的QoS技术底座与QoE感官革命
QoS 定义:QoS(Quality of Service,服务质量)衡量音视频传输技术层面的性能表现,聚焦网络传输和系统处理能力,通过客观指标量化服务质量。核心指标 码率/带宽:数据传输速率上限,直接…...
element-plus选择菜单栏不变色
代码: <template> ... <el-menu-item index"/task/execute"><el-icon><IconMenu /></el-icon><span>验收任务</span> </el-menu-item> <el-menu-item index"/task/change"><el-icon…...
uniapp加载json动画
一、添加canvas画布 <canvas id"lottie_demo" type"2d" style"display: inline-block;width: 148rpx; height: 148rpx;" /> 二、引入依赖和JSON文件 安装依赖 npm install lottie-miniprogram --save import lottie from lottie-mini…...
快递物流展同期举办2025中国智慧物流核心零部件创新论坛
2025中国智慧物流核心零部件创新论坛 会议主题:“AI ”重构智慧物流核心技术生态 会议介绍 随着人工智能、物联网、5G等技术的快速发展,智慧物流已成为全球物流行业转型升级的核心方向。在AI技术的驱动下,物流行业正从传统的“人、车、货”…...
ASP.NET图书馆借阅系统(源码+lw+部署文档+讲解),源码可白嫖!
摘要 近些年来,随着科技的飞速发展,互联网的普及逐渐延伸到各行各业中,给人们生活带来了十分的便利,图书馆借阅系统利用计算机网络实现信息化管理,使图书信息、图书借阅、归还的管理发展和服务水平有显著提升。 本文拟…...
在 Linux 终端中轻松设置 Chromium 的 User-Agent:模拟手机模式与自定义浏览体验
在 Linux 系统中,通过终端灵活控制 Chromium 的行为可以大幅提升工作效率。本文将详细介绍如何通过命令行参数和环境变量自定义 Chromium 的 User-Agent,并结合手机模式模拟,实现更灵活的浏览体验。 为什么需要自定义 User-Agent?…...
实验一 单管共射极放大电路
这篇文章是即兴写的,也不知道对不对,只有代码哦~~(文章结尾有彩蛋哦~~~) 表1-1实验数据MATLAB代码: clear all; clc % 参数设置 VCC 12; % 电源电压 (V) RB1 45e3; % 偏置电阻 RB1 (Ohms) RB2 15e3; % 偏置电阻 RB2 (Ohms) R…...
10-python面向对象(上)
10-python面向对象【上】 1.面向对象简介2. 类(class)3. 类的定义4. 参数self4.1 属性和方法4.2 self 1.面向对象简介 Python是一门面向对象的编程语言 所谓面向对象的语言,简单理解就是语言中的所有操作都是通过对象来进行的 面向过程: 面向过程指将我们…...
Java 大视界 -- 基于 Java 的大数据分布式缓存技术在电商高并发场景下的性能优化(181)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
Apache Airflow开源程序是一个以编程方式编写、计划和监控工作流程的平台
一、软件介绍 文末提供程序和源码下载 Apache Airflow开源程序是一个以编程方式编写、计划和监控工作流程的平台,当工作流被定义为代码时,它们将变得更加可维护、可版本化、可测试和协作性。使用 Airflow 将工作流创作为任务的有向无环图 (D…...
大数据学习(101)-spark的高可用模式
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一…...
数字内容体验驱动用户参与增效
数字体验驱动参与增长 在数字化竞争日益激烈的市场环境中,数字内容体验已成为撬动用户深度参与的核心杠杆。通过个性化推荐算法与跨渠道分发策略的协同作用,企业能够精准匹配用户兴趣点,将碎片化信息转化为连贯的价值链条。数据显示…...
一文详解OpenGL环境搭建:Ubuntu20.4使用CLion配置OpenGL开发环境
在计算机图形学的广阔领域中,OpenGL作为行业标准的图形库,为开发者提供了强大的工具集来创建从简单的2D图形到复杂的3D世界。然而,对于初学者而言,配置一个合适的开发环境是迈向成功的第一步。本文将详细介绍如何在Ubuntu 20.04.3 LTS操作系统上搭建基于CLion的OpenGL开发环…...
欧拉函数模板
1.欧拉函数模板 - 蓝桥云课 问题描述 这是一道模板题。 首先给出欧拉函数的定义:即 Φ(n) 表示的是小于等于 n 的数中和 n 互质的数的个数。 比如说 Φ(6)2,当 n 是质数的时候,显然有 Φ(n)n−1。 题目大意: 给定 n 个正整数…...
用PointNet++训练自己的数据集(语义分割模型semseg)
(1)训练部件分割(partseg)模型和检测自己点云并将结果保存txt,请看博主上两篇文章 (2)本文背景是将pipe点云上的缺陷和本体检测出来,即1种语义场景(pipe)&…...
Java反射机制深度解析:方法、实战与底层机制
大家好,我是钢板兽! 反射作为Java的特性,它不仅是Spring三大特性Ioc、DI、AOP的基础,而且MyBatis、Jackson序列化、rpc远程调用接口都用到了反射机制。 本文将带你系统性地掌握 Java 反射的使用,通过 JSON 反序列化的…...
查看wifi密码
netsh wlan show profile nameCMCC-Rkt_Wi-Fi5 keyclear CMCC-Rkt_Wi-Fi5是无线网名称...
RPC 发展史
RPC 发展史 RPC(Remote Procedure Call)即远程过程调用,随着微服务的兴起,每个服务都拥有自己的数据库,负责各自的模块,例如 keystone(认证服务)负责用户信息、权限认证的内容&…...
蓝桥杯基础算法-递归
代码简洁,但涉及到的运算,会随着递归层数的增加成指数级增长 路分析:第20行20列位于45度这条线上 这条线上的数字是1 5 13 25 41...两数之差:4 8 12 16 --->每一个都是在前面的基础上4,可以用递归或者循环 public class dem…...
山东大学离散数学第七章习题解析
参考教材:离散数学教程,徐秋亮 / 栾俊峰 / 卢雷 / 王慧 / 赵合计 编著,山东大学计算机科学与技术学院 注:该解析为个人所写,涵盖了 2022-2023-2 学期赵合计老师所布置的所有课本习题;由于学识、认识及经验…...
关于使用python 安装 flask-openapi3扩展,使用docker 环境的完整复盘
在某个时刻 需要运行python 3 flask-openapi3扩展 当前因为服务器为国产化服务器,操作系统版本为麒麟,python 版本为3.7 因为要安装flask-openapi3 包 又因为flask 版本小于2.0 from flask_openapi3 import OpenAPI,Info,Tag目前安装的是 …...
MybatisPlus的一些基本操作
mybatisplus分页 Testvoid testpage(){IPage<User> page new Page<>(1,3); userDao.selectPage(page,null);System.out.println("当前页码值:"page.getCurrent());System.out.println("每页显示数:"page.getSize());S…...
debian12安装mysql5.7.42(deb)
安装 官方文档 https://dev.mysql.com/doc/mysql-installation-excerpt/8.0/en/linux-installation-debian.html 上面是8.0的教程,服了我说怎么那么奇怪 5.7官方教程 https://dev.mysql.com/doc/mysql-installation-excerpt/5.7/en/linux-installation-debian.html …...
基于Python脚本实现Flink on YARN任务批量触发Savepoint的实践指南
基于Python脚本实现Flink on YARN任务批量触发Savepoint的实践指南 一、背景与价值 在流计算生产环境中,Flink on YARN的部署方式凭借其资源管理优势被广泛采用。Savepoint作为Flink任务状态的一致性快照,承载着故障恢复、版本升级、作业暂停等重要场景…...
Winform入门进阶企业级开发示例:http接口数据清洗转换、断线续传、mqtt数据传输实例详解(附代码资源下载)
场景 C#/Winform入门、进阶、强化、扩展、知识体系完善等知识点学习、性能优化、源码分析专栏分享: C#/Winform入门、进阶、强化、扩展、知识体系完善等知识点学习、性能优化、源码分析专栏分享_winform 强化学习-CSDN博客 如何将以上相关理论知识学以致用。下面针对Winform…...
PHP开发效率提升利器:通义灵码在VSCode中的应用与技巧
引言 在 PHP 开发领域,提高编码效率和质量是每位开发者追求的目标。通义灵码,作为一款由阿里云技术团队开发的智能编码助手,能够通过其强大的 AI 能力,为 PHP 开发者提供包括代码自动补全、智能注释、代码优化等多方面的支持。本…...
WHAT - React 错误边界处理 - react-error-boundary
目录 安装使用方式常用 Props使用场景 react-error-boundary 是一个由 Brian Vaughn 开发的 React 组件库,用于更方便地处理组件树中的错误(错误边界)。 阅读参考: React Error Boundariesreact-error-boundary 安装 npm inst…...
数据模型评估的四维黄金法则:从技术验证到业务价值证明
引言:为什么你的数据模型总被质疑? 在滴滴出行的一次核心业务会议上,数据团队与业务部门爆发了激烈争论:新上线的订单预测模型是否真的优于旧系统?数据工程师认为查询速度提升40%已是巨大成功,业务方却质疑…...
vscode ctrl+鼠标左键不能跳转
笔者使用的vscode版本是1.85.2(一周前从1.99降下来的,因为版本过高连不上服务器)。 使用python时突然发现代码看起来有些别扭,细看之下发现是import xxx语句中的包的颜色从之前的青色变成了现在的白色。再用ctrl左键点击包名试图…...
换动态IP对电脑有什么影响:全面解析与实用指南
在当今数字化时代,IP地址作为网络世界的"身份证",对我们的网络体验有着重要影响。许多用户出于某些原因,会考虑更换动态IP地址。那么,这种操作究竟会对我们的电脑产生哪些影响?是利大于弊还是弊大于利&#…...
Go语言从零构建SQL数据库(6) - sql解析器(番外)- *号的处理
番外:处理SQL通配符查询 在SQL中,SELECT * FROM table是最基础的查询之一,星号(*)是一个通配符,表示"选择所有列"。虽然通配符查询看起来简单,但在解析器中需要特殊处理。下面详细介…...