【Linux】进程周边007之进程控制
👀樊梓慕:个人主页
🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》《Linux》
🌝每一个不曾起舞的日子,都是对生命的辜负
目录
前言
1.进程创建
2.进程终止
2.1探究main函数返回值
2.2探究普通函数退出的执行情况
2.3进程退出的场景
2.4进程退出的方式
2.4.1main函数返回
2.4.2调用exit()
2.4.3调用_exit()
2.4.4exit与_exit的区别
2.4.5exit与_exit的关系
3.进程等待
3.1进程等待的必要性
3.2进程等待的方法
3.2.0输出型参数status
3.2.1wait方法
3.2.2waitpid方法
4.进程程序替换
4.1什么是进程程序替换?
4.2进程程序替换的细节
4.3进程程序替换的函数
4.2.1execl
4.2.1execlp
4.2.2execv
4.2.3execvp
4.2.4exec*可以执行系统的指令(程序),可以执行我们自己编写的程序么?
4.2.5execle
4.2.6execvpe
4.2.7execve
前言
本篇文章博主将会与大家共同学习进程控制的相关内容,快来一起学习吧。
欢迎大家📂收藏📂以便未来做题时可以快速找到思路,巧妙的方法可以事半功倍。
=========================================================================
GITEE相关代码:🌟fanfei_c的仓库🌟
=========================================================================
1.进程创建
进程创建的大部分内容其实我们已经在之前的文章就介绍的差不多了,比如fork函数创建子进程,fork函数的返回值的意义,以及写时拷贝等等,所以如果对这部分由疑问的话,大家可以到我的Linux专栏中找到进程概念了解fork函数的相关内容,找到进程地址空间了解写时拷贝的内容,这部分我就不再重复了。
樊梓慕-Linux专栏http://t.csdnimg.cn/piqro
2.进程终止
2.1探究main函数返回值
main函数的返回值是返回给谁的?
你可能会说是main函数的上层函数,但其实最终是通过加载器被操作系统调用的,也就是说main函数的返回值最终还是会给给操作系统,操作系统会读取main函数的返回值来检测进程的执行情况。
其实main函数的返回值具有特殊意义。
main函数的返回值叫做进程的退出码。
我们可以利用main函数不同的返回值表示不同的失败原因。
- 当返回0时,代表进程执行成功。
- 当返回其他非0数字时,代表着不同的错误原因。
我们可以用echo $?的指令来获取最近一次执行的进程的退出码:
比如:
注意:指令也是进程,只要是进程就会有退出码,所以只要你输入的指令正常执行了,查询到的退出码也是0。
另外我们可以将退出码转化成为进程执行是否顺利的信息。
当然执行成功我们不需要知道为什么成功,只需要知道失败为什么而失败。
所以我们可以使用语言和系统自带的一些方法,进行转化:
比如在之前学习C语言时strerror函数可以通过退出码获取该退出码对应的错误信息:
当然我们也可以自己设置退出码的字符串含义。
注意:其他函数退出,仅仅表示函数调用完毕。
2.2探究普通函数退出的执行情况
前面说普通函数退出,仅表示调用完毕,那我们怎么知道函数的执行情况呢?
调用函数,我们通常想看到两种结果:
- 函数的执行结果;
- 函数的执行情况。
比如fopen函数,当他成功时返回的是文件指针,失败时返回NULL,但我们如何知道更多有关失败的信息呢?
所以当fopen失败时会有错误码errno被设置,如:
注意:这里的函数都指的是库函数,我们自己定义的函数在退出时不会有错误码被设置,当然你可以自己设计。
2.3进程退出的场景
- 代码运行完毕,结果正确
- 代码运行完毕,结果不正确
- 代码异常终止
我们肯定要先确定代码会不会有异常,然后再去看结果是否正确。(异常之后,退出码无意义)
所以什么是异常?
异常的本质实际上就是进程收到了异常信号。
我们模拟一下:
kill -l查看信号: 我们向该进程发送8号信号:
所以说异常就是进程收到了异常信号。
另外每个信号都有自己对应的编号,后面的内容是数字的宏名称。
所以不同的信号编号对应着不同的异常原因。
结论:进程最终的执行情况可用两个数字来表示,这两个数字一个为信号编号,一个为退出码。
2.4进程退出的方式
2.4.1main函数返回
我们可以用main函数return的方式退出进程。
2.4.2调用exit()
exit就是用来终止进程的,status代表着退出码,在我们的进程代码中,任意地方调用exit,都表示进程退出。
2.4.3调用_exit()
_exit属于2号手册,是系统调用,但也是可以用作终止进程。
2.4.4exit与_exit的区别
exit支持刷新缓冲区,_exit不支持刷新缓冲区!
什么意思呢?
首先:要知道利用printf打印内容时如果不加\n,该内容不会立即刷新出来,而是处在缓冲区内。
有了这个基础我们就来验证一下:
我们发现四秒后执行exit,缓冲区内的内容仍然被刷新了出来,所以exit支持刷新缓冲区!
我们发现四秒后执行_exit,缓冲区内的内容并没有刷新出来,所以_exit不支持刷新缓冲区!
2.4.5exit与_exit的关系
谁才有资格终止进程??
只有操作系统才能够终止进程,所以想要终止进程必须要调用系统调用_exit,所以exit的底层就是封装的_exit。
- 扩展:printf和scanf属于库函数,有资格对硬件写入么??所以printf和scanf的底层也必然封装了系统调用接口
思考:为什么要有exit这样的库函数封装系统调用接口,直接使用系统调用接口不好么?
首先语言要封装肯定是有要满足语言的特性或者为了简化使用系统调用的成本,但这些我们今天不考虑。
语言是如何具有跨平台性的?
不同的系统他们的系统调用肯定是不一样的,所以语言就对这些系统调用做了封装,从而在库的层面上把底层的差异化通过库的封装给屏蔽掉了!
3.进程等待
3.1进程等待的必要性
之前讲过,子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。
另外,进程一旦变成僵尸状态,那就刀枪不入,kill -9 也无能为力,因为谁也没有办法杀死一个已经死去的进程。
最后,我们需要知道父进程派给子进程的任务完成的如何。
父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息。
3.2进程等待的方法
3.2.0输出型参数status
进程等待所用的两个函数wait和waitpid,都有一个status参数,该参数是一个输出型参数,由操作系统进行填充。
如果不关心子进程的退出状态信息,则可以对status参数传入NULL。否则,操作系统会通过该参数,将子进程的退出信息反馈给父进程。
status是一个整型变量,但status不能当作整型来看待,status的不同比特位所代表的信息不同,具体细节如下(这里我们只研究status低16比特位):
如图所示0-6位的七个比特位代表终止信号,而8-15位的八个比特位代表退出状态信息,这也刚好说明了:进程最终的执行情况可用两个数字来表示。
那我们可以尝试通过对status进行位操作来获取下终止信号和退出码:
exitCode = (status >> 8) & 0xFF; //退出码
exitSignal = status & 0x7F; //退出信号
那我们每次都需要通过位操作来获取这两个数字么??
系统当中提供了两个宏来获取退出码和退出信号。
- WIFEXITED(status):若为正常终止子进程返回的状态则为真(查看进程是否正常退出)W(wait) IF(if) EXITED(正常退出)
- WEXITSTATUS(status):若WIFEXITED为零则提取子进程的退出码。(查看进程的退出码)W(wait) EXIT(exit) STATUS(状态)
exitNormal = WIFEXITED(status); //是否正常退出
exitCode = WEXITSTATUS(status); //获取退出码
3.2.1wait方法
pid_t wait(int *status)
等待任意一个子进程直到父进程读取到子进程的退出信息(阻塞等待),默认为阻塞等待。
返回值:
- 成功返回等待的子进程pid,失败返回-1。
参数:
- status:若不关心子进程的退出状态信息,则可以对status参数传入NULL。
3.2.2waitpid方法
pid_t waitpid(pid_t pid,int *status,int options);
返回值:
- 等待成功返回被等待进程的pid。
- 如果设置了选项
WNOHANG
,而调用中waitpid发现没有已退出的子进程可收集,则返回0。 - 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在。
参数:
- 当参数pid=-1时,则等待任意子进程。
- 当参数pid>0时,等待进程标识符为pid的子进程。
- status:若不关心子进程的退出状态信息,则可以对status参数传入NULL。
- 当options=0时,为阻塞等待。
- 当options=
WNOHANG
时,为非阻塞等待,即父进程检测到子进程没有退出会立即返回0不会一直等待什么也不做(操作系统会循环式的检测子进程是否退出,这叫做基于非阻塞的轮询访问),而如果返回值小于0则代表等待失败,大于0代表等待成功并返回被等待进程的pid。 - 非阻塞等待的优点是:轮询期间不要傻傻的等着,可以做做其他事情。
小贴士:HANG其实就是一种死机的说法,所以这里的WNOHANG可以记为W(wait) NO(no) HANG。
思考:为什么需要waitpid这个系统调用来获取进程的退出码和信号?
利用两个全局变量,当进程哪里出问题时,我自己修改全局变量的值改成对应的退出码和信号不就行了么?
注意:进程独立性!!
- 因为全局变量属于父进程,子进程要对该共享变量修改,会发生写时拷贝,子进程退出时,父进程接收不到修改后的信息,进程的独立性!!
所以必须需要系统调用,当子进程退出时,会释放掉进程地址空间、页表等,只留一个PCB,PCB中会保存这两个数字,所以当父进程回收子进程时,通过系统调用waitpid(注意:父进程不能直接访问子进程的PCB,这也是通过系统调用才能拿到的,操作系统不相信任何人)就能拿到退出进程的退出码和信号了,此时才可以将这两个数字写入到整型变量status!
4.进程程序替换
4.1什么是进程程序替换?
我们创建的子进程可以执行其他程序的代码么?
可以,这就需要用到进程程序替换的知识了。
若想让子进程执行另一个程序,需要调用一种exec函数。
当进程调用exec函数时,该进程的物理内存上的代码和数据完全被新程序替换,并从新程序的启动例程开始执行。
也就是说不影响进程PCB、进程地址空间和页表,将替换执行的程序的代码和数据覆盖到原来的进程物理内存上!
思考:进程程序替换时,有没有创建新的进程?
不会,只是进程在物理内存中的代码和数据发生了改变,进程的PCB、进程地址空间、页表都没有改变,所以并没有创建新的进程。
思考:子进程进行进程程序替换会不会影响父进程的代码和数据?
不会,当检测到子进程进行进程程序替换时会发生写时拷贝(因为对之前父子共享的代码和数据进行了修改(写入),所以会发生写时拷贝),此后父子进程的代码和数据也就分离了,所以子进程进行进程程序替换后不会影响父进程的代码和数据。
4.2进程程序替换的细节
- 程序替换一旦成功,原来的后续的代码将不会执行,因为被替换掉了。
- 进程程序替换接口只有失败返回值,没有成功返回值。(因为如果成功代表着程序被替换掉了)
- 替换完成,不创建新的进程。
- 进程程序替换接口其实就是扮演的加载器的角色,如果没有要替换的程序就是加载。(将程序加载到内存)。
4.3进程程序替换的函数
我们发现进程程序替换函数都是exec+p/l/v/e。他们分别暗指什么意思呢?
函数名中'p'的含义(PATH):
- 程序替换函数中名字带'p'的参数一般传程序的名字即可,他会自己到环境变量PATH的路径下查找该程序。
- 名字不带'p'的参数一般传绝对路径。
函数名中'l'和'v'的含义(list/vector):
- 名字中带'l'的,一般后面的参数是以列表list形式呈现的,如
execl("/usr/bin/ls","ls","-a","-l",NULL);
- 名字中带'v'的,一般后面的参数是以数组vector形式呈现的,如
char* myargv[] = { "ls", "-a", "-i", "-l", NULL };
execv("/usr/bin/ls", myargv);
函数名中'e'的含义(环境变量):
- 名字中带'e'的,一般表示可以给替换后的程序传递全新的环境变量表。
4.2.1execl
int execl(const char *path, const char *arg, ...);//...为可变参数,可类比printf函数
参数:
- const char *path:程序的路径
- const char *arg:要进行的操作,可变参数列表
实例:
4.2.1execlp
int execlp(const char *file, const char *arg, ...);
参数:
- const char *file:程序名称
- const char *arg:要进行的操作,可变参数列表
实例:
execlp("ls", "ls", "-a", "-l", NULL);
4.2.2execv
int execv(const char *path, char *const argv[]);
参数: 略。
实例:
char* myargv[] = {"ls", "-a", "-l", NULL};
execv("/usr/bin/ls", myargv);
4.2.3execvp
int execvp(const char *file, char *const argv[]);
参数:略。
实例:
char* myargv[] = {"ls", "-a", "-l", NULL};
execvp("ls", myargv);
4.2.4exec*可以执行系统的指令(程序),可以执行我们自己编写的程序么?
首先我们来插一句题外话
makefile如何写可以在make时对两个文件进行编译链接形成两个可执行程序呢?
我们知道makefile从上到下进行扫描时默认只会生成一个可执行程序(从上往下第一个)。
那如何处理呢?
因为all依赖于myprocess和mytest,所以这两个必然会被生成,但是不给all依赖方法,也就是说啥也不干,所以就能形成两个可执行程序了。
写一段C++代码,一会做程序替换用:
测试用函数:
通过执行myprocess,就能观察到替换后的执行情况:
所以可以执行我们自己编写的程序,无论是什么语言(因为最终都会生成可执行程序)。
根据上面的例子我们发现进程替换时传递了命令行参数,那环境变量参数呢?其实有这样的参数可以给替换后的程序传递全新的环境变量信息。(注:子进程和替换后的进程用的同一个进程地址空间,所以环境变量依旧会被继承下去,虽然替换后代码和数据会写时拷贝,但环境变量部分不受影响)
接下来我们学习另外两个程序替换函数:
4.2.5execle
int execle(const char *path, const char *arg, ..., char *const envp[]);
参数:
- const char *path:程序的路径
- const char *arg:要进行的操作,可变参数列表
- char *const envp[]:要覆盖的全新的环境变量
实例:
4.2.6execvpe
参数:略。
实例:
char* const env[]={"PATH=/","value=a"};
char* myargv[] = {"ls", "-a", "-l", NULL};
execvpe("ls", myargv, env);
4.2.7execve
看到这你会发现以上的六种函数功能十分相似,因为他们都是由execve这个系统调用封装而来的!
=========================================================================
如果你对该系列文章有兴趣的话,欢迎持续关注博主动态,博主会持续输出优质内容
🍎博主很需要大家的支持,你的支持是我创作的不竭动力🍎
🌟~ 点赞收藏+关注 ~🌟
=========================================================================
相关文章:
【Linux】进程周边007之进程控制
👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》 🌝每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.进程创建 2.进程终止 2.…...
【C++】vector容器的模拟实现
目录 一,框架设计 二,构造函数 三,析构函数 四,赋值运算符 五,容器接口的实现 1,迭代器实现 2,“ [] ”运算符的实现 3,swap交换和resize重设大小 4,insert插入…...
华为Harmony——ArkTs语言
文章目录 一、简单示例二、声明式UI描述创建组件无参有参数 配置属性配置事件配置子组件 三、自定义组件基本用法基本结构成员函数/变量 一、简单示例 我们以一个具体的示例来说明ArkTS的基本组成。如下图所示,当开发者点击按钮时,文本内容从“Hello Wo…...
uniapp使用colorUI
colorUI 微动画 | ColorUI 使用文档 1:把colorui里三个文件复制到自己项目中去 App.vue </script> <style> import url(colorui/icon.css); import url(colorui/main.css); import url("colorui/animation.css");-webkit-keyframes show {…...
浅谈测试自动化selenium之POM模式
基于本人也是一个初学者,在运用POM模式的时候记录一下自己的学习笔记。 如果你是大神,那么可以略过,如果你是初学者,希望对你有帮助。 本文阐述了以下几个问题: 什么叫POM模式 为什么要用POM模式 POM模式的思想 POM模…...
什么是事件传播、事件冒泡、事件捕获?
一、事件传播 1、概述 (1)当事件发生在DOM元素上时,该事件并不完全发生在那个元素 (2)在冒泡阶段中,事件冒泡或向上传播至父级、祖父级、祖父的父级,直到 window 为止 (3&#x…...
【uniapp】uniapp中本地存储sqlite数据库保姆级使用教程(附完整代码和注释)
数据库请求接口封装 uniapp中提供了plus.sqlite接口,在这里我们对常用的数据库请求操作进行了二次封装 这里的dbName、dbPath、recordsTable 可以根据你的需求自己命名 module.exports {/** * type {String} 数据库名称*/dbName: salary,/*** 数据库地址* type {…...
微软推出了GPT-RAG:这是一个机器学习库,为在Azure OpenAI上使用RAG模式生产部署大型语言模型(LLMs)提供了企业级参考架构
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
Centos系统升级gcc版本
自己环境的gcc版本太低,影响使用SAN全家桶进行内存泄露检查 当前环境gcc版本查看 gcc --version 进行升级: 1、安装EPEL存储库 yum install epel-release -y 2、确保系统已经更新到最新版本 yum update -y 3、安装GCC编译器及其相关工具包 yum g…...
Http---HTTP响应报文
1. HTTP响应报文分析 HTTP 响应报文效果图: 响应报文说明: --- 响应行/状态行 --- HTTP/1.1 200 OK # HTTP协议版本 状态码 状态描述 --- 响应头 --- Server: Tengine # 服务器名称 Content-Type: text/html; charsetUTF-8 # 内容类型 Transfer-Encoding: chunked # 发送给客…...
iOS 开发设计 App 上架符合要求的截图
1. 真机运行截屏 2. 可以在 Apple developer 官网 Design 下找到 iPhone 边框 https://developer.apple.com/design/resources/ 不用这个边框也行,可以参考已上架 App 的图片框 3. 使用 Procreate(PhotoShop)创建符合要求的画布大小 4. 导入…...
DRF之引入
目录 一、web应用模式 【1】前后端混合开发 【2】前后端分离 二、API接口 三、接口测试工具:Postman 四、RESTful API规范 【1】什么是RESTful 【2】RESTful API的规范 2.1 数据的安全保障 2.2 接口特征表现 2.3 多数据版本共存 2.4 数据即是资源&#…...
【Skynet 入门实战练习】事件模块 | 批处理模块 | GM 指令 | 模糊搜索
文章目录 前言事件模块批处理模块GM 指令模块模糊搜索最后 前言 本节完善了项目,实现了事件、批处理、模糊搜索模块、GM 指令模块。 事件模块 什么是事件模块?事件模块是用来在各系统之间传递事件消息的。 为什么需要事件模块?主要目的是…...
Web组态可视化编辑器-by组态
演示地址: http://www.by-lot.com http://www.byzt.net web组态可视化编辑器:引领未来可视化编辑的新潮流 随着网络的普及和快速发展,web组态可视化编辑器应运而生,为人们在网络世界中创建和编辑内容提供了更加便捷的操作方式。这…...
PDF.js介绍以及使用
一、PDF.js是什么 PDF.js是一个JavaScript库,可以在现代Web浏览器中渲染和显示PDF文件。它的主要作用是将PDF文件转换为HTML5格式,以便在浏览器上进行展示和交互。 PDF.js的主要功能包括: 在浏览器中显示PDF:PDF.js使用HTML5的…...
经常使用的排序算法
一、直接插入排序 #include <stdio.h>void insert_sort(int arr[], int n){int i, j, tmp;for (i 1; i < n; i){tmp arr[i];j i - 1;while (j > 0 && arr[j] > tmp){ // 将要插入的元素与数组中的元素比较(从后向前比)arr[j …...
msyql 24day 数据库主从 主从复制 读写分离 master slave 有数据如何增加
目录 环境介绍读写分离纵向扩展横向扩展 数据库主从准备环境主库环境(master)从库配置(slave)状态分析重新配置问题分析 报错解决从库验证 有数据的情况下 去做主从清理环境环境准备数据库中的锁的机制主库配置从库配置最后给主库解锁常见错误 环境介绍 将一个数据库的数据 复…...
使用 Taro 开发鸿蒙原生应用 —— 探秘适配鸿蒙 ArkTS 的工作原理
背景 在上一篇文章中,我们已经了解到华为即将发布的鸿蒙操作系统纯血版本——鸿蒙 Next,以及各个互联网厂商开展鸿蒙应用开发的消息。其中,Taro作为一个重要的前端开发框架,也积极适配鸿蒙的新一代语言框架 —— ArkTS。 本文将…...
Linux下 自定义多线程并发快速压缩解压缩脚本
文章目录 自定义多线程压缩解压缩脚本使用 Linux下 自定义多线程并发快速压缩解压缩脚本 Linux下常用的tar工具无法支持并行 压缩和解压,对于大量小文件的解压缩,可借助pigz工具实现多线程并行工作,实现更为高效的压缩和解压缩。 自定义多线…...
ubuntu20.04下安装pcl_ubuntu安装pcl
pcl点云数据库,用来进行3D信息的获取与处理,和opencv相比较,opencv是用来处理二维信息,他是学术界与工业界针对点云最全的库,且网络上相关的资料很多。以下是pcl的安装步骤以及遇到的问题。 提前说明,本人…...
阿里云常用配置:日志采集、OSS、RAM 权限策略
文章目录 引言I 日志采集1.1 具体查询语法1.2 查询示例1.3 设置token时间(登录过期时间)II OSS2.1 设置防盗链2.2 验证Referer防盗链是否生效III 通义灵码 (智能编码)IV RAM 权限策略4.1 短信策略4.2 内容风险检测引言 SLS I 日志采集...
回顾丨2023 SpeechHome 第三届语音技术研讨会
下面是整体会议的内容回顾: 18日线上直播回顾 18日上午9:30,AISHELL & SpeechHome CEO卜辉宣布研讨会开始,并简要介绍本次研讨会的筹备情况以及报告内容。随后,CCF语音对话与听觉专委会副主任、清华大学教授郑方,…...
【flink】状态清理策略(TTL)
flink的keyed state是有有效期(TTL)的,使用和说明在官网描述的篇幅也比较多,对于三种清理策略没有进行横向对比得很清晰。 全量快照清理(FULL_STATE_SCAN_SNAPSHOT)增量清理(INCREMENTAL_CLEANUP)rocksdb压缩清理(ROCKSDB_COMPACTION_FILTER) 注意&…...
4. 行为模式 - 中介者模式
亦称: 调解人、控制器、Intermediary、Controller、Mediator 意图 中介者模式是一种行为设计模式, 能让你减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互, 迫使它们通过一个中介者对象进行合作。 问题 假如你有一个创建…...
2015年第四届数学建模国际赛小美赛A题飞机上的细长座椅解题全过程文档及程序
2015年第四届数学建模国际赛小美赛 A题 飞机上的细长座椅 原题再现: 航空公司座位是指在旅途中乘客可以乘坐的座位。一些航空公司现在推出了新的经济舱“超薄”座位。这些座椅除了重量较轻外,理论上还允许航空公司在不显著影响乘客舒适度的情况下增加运…...
机器学习笔记(二)使用paddlepaddle,再探波士顿房价预测
目标 用paddlepaddle来重写之前那个手写的梯度下降方案,简化内容 流程 实际上就做了几个事: 数据准备:将一个批次的数据先转换成nparray格式,再转换成Tensor格式前向计算:将一个批次的样本数据灌入网络中ÿ…...
【Linux】权限篇(二)
权限目录 1. 前言2. 权限2.1 修改权限2.2 有无权限的对比2.3 另外一个修改权限的方法2.3.1 更改用户角色2.3.2 修改文件权限属性 3. 第一个属性列4. 目录权限5. 默认权限 1. 前言 在之前的一篇博客中分享了关于权限的一些知识,这次紧接上次的进行,有需要…...
reduce累加器的应用
有如下json数据,需要统计Status的值为0和1的数量 const data {"code": "001","results": [{"Status": "0",},{"Status": "0",},{"Status": "1",}] }方法一:用reduce方…...
助力硬件测试工程师之EMC项目测试。
1:更新该系列的目的 接下来的一个月内,将更新硬件测试工程师的其中测试项目--EMC项目,后续将会出安规等项目,助力测试工程师的学习。 2:如何高效率的展现项目的基础以及一些细节知识点 通过思维导图以及标准的规定进行…...
Github 2023-12-23 开源项目日报 Top10
根据Github Trendings的统计,今日(2023-12-23统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目6C项目2C项目1Jupyter Notebook项目1HTML项目1Go项目1非开发语言项目1 免费API集体清单 创建周期…...
生产软件/seo优化与品牌官网定制
摘要: 手把手教你用(Python)零起步数学神经网络入门!在这篇文章中,我们将在Python中从头开始了解用于构建具有各种层神经网络(完全连接,卷积等)的小型库中的机器学习和代码。最终,我们将能够写出如下内容:假…...
谁做违法网站/企业品牌策划
引言 线程池很普通的老话题,讨论的很多.深入的不多,也就那些基础库中才能见到这种精妙完备的技巧.而本文随大流 想深入简述一种高效控制性强的一种线程池实现. 先引入一个概念, 惊群. 简单举个例子. 春天来了, 公园出现了很多麻雀. 而你恰巧有一个玉米粒. 扔出去, 立马无数麻雀…...
wordpress粘贴文章/抖音seo排名系统哪个好用
A1,A2...An乘积,括号次序关键...
品牌网站建设c重庆/如何做网络营销?
文章目录Search模块根据不同参数获取数据展示封装数据请求根据参数获取数据监听路由的变化再次发起请求获取数据Search模块根据不同参数获取数据展示 封装数据请求 由于Search模块搜索通常是多次,因此发送数据请求页会是多次,而在上一节中,…...
织梦wordpress帝国对比/市场调研流程
大浪淘沙的AI创业圈,触景无限正在这个技术浪潮中不断找寻自己的位置。 有人说,AI创业的大门已经慢慢关闭,场内的玩家也已基本定型,未来的战争将聚焦在头部几家,马太效应的收紧会使得一大波竞逐者生存艰难,…...
四川城乡建设官方网站/关键词点击价格查询
课程目标: ① 在Servlet中懂得ServletContext HttpSession 以及HttpServletRequest之间的关系 ② 懂得怎样使用它们 概念介绍: 1. [共同点]不管对象的作用域怎样,共享变量和获得变量的 方法都是一致的 –setAttribute(“varName”,obj); –ge…...