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

板凳----Linux/Unix 系统编程手册 25章 进程的终止

25.1 进程的终止:_exit()和exit() 440

1. _exit(int status), status 定义了终止状态,父进程可调用 wait 获取。仅低8位可用,调用 _exit() 总是成功的。
2.程序一般不会调用 _exit(), 而是调用库函数 exit()。exit() 执行如下动作:1.调用退出处理程序(通过 atexit() 和 on_exit() 注册的函数),其执行顺序与注册顺序相反。2.刷新 stdio 流缓冲区3.使用由 status 提供的值执行 _exit() 系统调用。
与专属的Unix的 _exit 不同, exit() 则属于标准C语言函数库。

25.2 进程终止的细节 441

无论进程是否正常终止,都会发生如下动作:
1.关闭所有打开文件描述符,目录流,信息目录描述符,以及转换描述符
2.作为文件描述符关闭的后果之一,将释放该进程所持有的任何文件锁
3.分离任何已经连接的 System V 共享内存段,且对应于各段的 shm_nattch 计数器值减一
4.进程为每个 System V 信号量所设置的 semadj 值将会被加到信号量值中。
5.如果该进程是一个管理终端的管理进程,那么系统会向该终端前台进程组中的每个进程发送 sighup 信号,
接着终端会于会话脱离。
6.将关闭该进程打开的任何 POSIX 有名信号量,类似调用 sem_close()
7.将关闭该进程打开的任何 POSIX 消息队列,类似于调用 mq_close()
8.作为进程退出的后果之一,如果某进程组称为孤儿,且该组中存在任何已停止进程,则组中所有进程都将收到 sighup
信号,随着为 sigcont 信号。
9.移除该进程通过 mlock() 和 mlockall() 锁建立的任何内存锁
10.取消该进程调用 mmap() 所创建的任何内存映射。

25.3 退出处理程序 442

退出处理程序是一个由程序设计者提供的函数,可于进程生命周期的任意时间点注册,并在该进程调用 exit() 正常终止时
自动执行。如果程序直接调用 _exit() 或者因信号而异常终止,则不会调用退出处理程序。
当程序收到信号而终止时,将不会调用退出处理程序。这一事实一定程序上限制了它们的效用。此时最佳的应对方式莫若为可能发送
给进程的信号建立信号处理程序,并于其中设置标志位,领主程序据此来调用 exit()。因为 exit() 不属于异步信号安全函数,所有通常
不能在信号处理程序中对其发起调用。
注册退出处理程序
atexit();
1.概念:一般内核中每个启动的进程默认都有一个标准的默认终止函数,用于在进程终止时执行的函数,该函数主要用来释放进程所占用的资源,也可以自定义终止函数。按照ISO C规定,一个进程可以注册32个终止函数,这些函数将由exit函数自动调用。
   登记的终止函数以栈的形式运行,先注册的后执行。如果自定义注册了进程终止函数,那么内核提供的默认的终止函数将会被覆盖。
原文链接:https://blog.csdn.net/qq_35733751/article/details/82392918
希望进程在结束时,进行一些清理工作,比如某些重要的数据保存到文件中。如果不登记终止函数的话,实现这个操作是有些困难的,因为进程有可能是因为某个函数调用失败,且该函数出错时又调用了exit函数导致进程终止,更糟糕的是出错的函数是不确定的。这个时候就可以通过登记注册终止函数,这样进程在终止时,会自动执行注册的终止函数把数据保存到文件中,方便了许多。
2. atexit函数语义
  atexit函数是用来在内核中注册一个进程终止时执行的函数,通过atexit函数所包含的头文件来看,atexit函数是一个C库函数。

函数原型:

#include <stdlib.h>
int atexit(void(*function)(void));atexit函数的参数是一个函数指针,表示注册的终止函数,终止函数语法格式为:void(*function)(void) 。返回值:成功返回0,失败返回不一定是-1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>//以下func1,func2,func3都是线程终止函数
void term_func1(void){puts("term func1");
}
void term_func2(void){puts("term func2");
}
void term_func3(void){puts("term func3");
}int main(int argc , char *args[]){if(argc < 3){fprintf(stderr,"use: %s file[exit | _exit | return]\n" ,args[0]);exit(0);}//注册终止函数atexit(term_func1);atexit(term_func2);atexit(term_func3);//打开文件FILE *fp = fopen(args[1] , "w");if(NULL == fp){perror("fopen");exit(-1);}//向文件写入数据fprintf(fp , "hello linux");if(!strcmp(args[2], "exit")){exit(0);        //标准C库函数}else if(!strcmp(args[2], "_exit")){_exit(0);       //系统调用}else if(!strcmp(args[2], "return")){return 0;       //正常返回}else{fprintf(stderr,"use: %s file[exit | _exit | return]\n", args[0]);}exit(0);
}

通过atexit函数注册的终止函数并非在所有情况下都会被调用,是否调用终止函数这取决于进程的终止方式

(base) wannian07@wannian07-PC:~/Desktop/std/linux prog$ gcc -o atexit_process atexit_process.c -lpthread
(base) wannian07@wannian07-PC:~/Desktop/std/linux prog$ ./atexit_process test.txt return
term func3
term func2
term func1
(base) wannian07@wannian07-PC:~/Desktop/std/linux prog$ cat test.txt
hello linux
当前进程以return形式退出,终止函数是以栈的形式执行的,先注册的终止函数后执行。然后通过cat命令查看test.txt文件的内容为hello linux 。
(base) wannian07@wannian07-PC:~/Desktop/std/linux prog$ ./atexit_process test.txt exit
term func3
term func2
term func1
(base) wannian07@wannian07-PC:~/Desktop/std/linux prog$ cat test.txt
hello linux
exit方式和return方式的结果是一样的,也调用了注册的终止函数。

(base) wannian07@wannian07-PC:~/Desktop/std/linux prog$ ./atexit_process test.txt _exit
(base) wannian07@wannian07-PC:~/Desktop/std/linux prog$ cat test.txt
_exit方式和前两种有所不同,之前注册的进程终止函数一个都没有执行,另外,test.txt文件倒是创建了,但是使用cat命令查看文件中并没有内容。
总结

不同的进程终止方式会产生不同的结果,如果我们选择return方式和exit方式,进程在终止之前会调用注册的进程终止函数,但是选择_exit方式,就算注册了终止函数,进程在终止之前也不会调用。

另外,需要注意的是在程序中写入文件数据用的函数是一个标准C库函数,在使用fprintf函数写入数据时,实际上数据并不会写入文件,而是先写入buff缓冲区中,这种方式也叫全缓存,只有当缓冲区写满或者调用fclose函数才会把数据写入文件中。

当程序终止时也会把数据写入文件,但是会有一些区别,如果使用return方式和exit方式让程序退出,会刷新buf中的数据到文件中,但是以_exit方式让程序退出,是不会刷新数据到文件中。

_exit是系统调用,进程终止前,不会调用终止函数,也不会刷新数据到文件中,而是直接进入内核。而exit和return是标准库函数,进程终止前,会调用终止函数,也会刷新数据到文件中。

因此我们可以把进程终止方式简单总结为:
在这里插入图片描述

图1-进程终止方式

进程启动和退出——atexit函数

下面这种图也证实了exit函数内部调用了_exit函数。

图2-进程的启动和退出过程
在这里插入图片描述

进程的启动和退出过程大概如图2所示:
  1.进程在运行时,首先内核会先启动一个例程,这个例程的作用是加载程序运行的参数,环境变量,在内核注册终止函数等这些工作,然后启动例程会调用main函数。

2.main函数调用了exit函数使进程终止退出,在进程终止之前,如果注册了终止函数,那么exit函数会先去依次调用进程终止函数,注册了几个就调用几个,每调用完一个终止函数并返回,调用顺序是以栈的形式来调用,然后调用flush刷新IO缓冲区的数据再返回,最后调用了系统调用_exit或_Exit,然后进程终止退出。

3.值得注意的是main函数也可以通过调用系统调用_exit直接进入内核使进程终止并退出,通过调用系统调用的方式使进程终止的话,并不会调用注册的进程终止函数。也可以通过main函数调用用户函数,然后用户函数调用exit,然后依次调用进程终止函数,再调用标准I/O函数刷新缓冲区,最后调用系统调用_exit使进程终止退出。

4.当然,用户函数也是可以直接通过系统调用_exit()进入内核使进程终止退出的。
原文链接:https://blog.csdn.net/qq_35733751/article/details/82392918
一个操作系统的实现https://blog.csdn.net/chuanwang66/category_8332297.html
on_exit();
用来注册执行exit()函数前执行的终止处理程序。
函数声明

#include <stdlib.h>
int on_exit(void (*function)(int , void *), void *arg);

功能描述
  on_exit()用来注册终止处理程序,当程序通过调用exit()或从main 中返回时被调用, 终止处理程序有两个参数,第一个参数是来自最后一个exit()函数调用中的status,第二个参数是来自on_exit()函数中的arg;
  同一个函数若注册多次,那它也会被调用多次;
  当一个子进程是通过调用fork()函数产生时,它将继承父进程的所有终止处理程序。在成功调用exec系列函数后,所有的终止处理程序都会被删除。
返回值

成功返回0,失败返回非0值。

#define _BSD_SOURCE     /* Get on_exit() declaration from <stdlib.h> */
#include <stdlib.h>
#include "tlpi_hdr.h"#ifdef __linux__        /* Few UNIX implementations have on_exit() */
#define HAVE_ON_EXIT
#endifstatic void
atexitFunc1(void)
{printf("atexit function 1 called\n");
}static void
atexitFunc2(void)
{printf("atexit function 2 called\n");
}#ifdef HAVE_ON_EXIT
static void
onexitFunc(int exitStatus, void *arg)
{printf("on_exit function called: status=%d, arg=%ld\n",exitStatus, (long) arg);
}
#endifint
main(int argc, char *argv[])
{
#ifdef HAVE_ON_EXITif (on_exit(onexitFunc, (void *) 10) != 0)fatal("on_exit 1");
#endifif (atexit(atexitFunc1) != 0)fatal("atexit 1");if (atexit(atexitFunc2) != 0)fatal("atexit 2");
#ifdef HAVE_ON_EXITif (on_exit(onexitFunc, (void *) 20) != 0)fatal("on_exit 2");
#endifexit(2);
}

(base) wannian07@wannian07-PC:~/Desktop/std/linux prog$ gcc exit_handlers.c -o exit_handlers error_functions.c curr_time.c get_num.c
(base) wannian07@wannian07-PC:~/Desktop/std/linux prog$ ./exit_handlers
on_exit function called: status=2, arg=20
atexit function 2 called
atexit function 1 called
on_exit function called: status=2, arg=10

25.4 fork()、stdio缓冲区以及_exit()之间的交互 445

#include "tlpi_hdr.h"int
main(int argc, char *argv[])
{printf("Hello world\n");write(STDOUT_FILENO, "Ciao\n", 5);if (fork() == -1)errExit("fork");/* Both child and parent continue execution here */exit(EXIT_SUCCESS);
} 

(base) wannian07@wannian07-PC:~/Desktop/std/tlpi-dist/procexec$ make fork_stdio_buf
cc -std=c99 -D_XOPEN_SOURCE=600 -D_DEFAULT_SOURCE -g -I…/lib -pedantic -Wall -W -Wmissing-prototypes -Wno-sign-compare -Wno-unused-parameter fork_stdio_buf.c …/libtlpi.a …/libtlpi.a -lm -o fork_stdio_buf
(base) wannian07@wannian07-PC:~/Desktop/std/tlpi-dist/procexec$ ./fork_stdio_buf
Hello world
Ciao
(base) wannian07@wannian07-PC:~/Desktop/std/tlpi-dist/procexec$ ./fork_stdio_buf > a
(base) wannian07@wannian07-PC:~/Desktop/std/tlpi-dist/procexec$ cat a
Ciao
Hello world
Hello world

printf() 信息输出了2次,是在进程的用户空间内存维护 stiod 缓冲区的。因此,通过 fork 创建的子进程会复制这些缓冲区。

父子进程调用 exit() 时,会各自刷新 stdio 缓冲区,从而导致重复输出。

可以采用以下2种方法避免:
1.可以在调用 fork 之前,使用 fflush() 来刷新 stdio 缓冲区,作为另外一种选择,使用 setvbuf() 和 setbuf() 来关闭 stdio 流缓冲。
2.子进程可以调用 _exit() 而非 exit(),以便不刷新 stdio 缓冲区。
这一技术例证了更为通用的原则:在创建子进程的应用中,典型情况下仅一个进程(一般为父进程)应通过调用 exit() 终止,而其他进程应调用 _exit()终止,
从而确保一个进程调用退出处理程序刷新 stdio 缓冲区。

write 并未出现2次,是因为 write 会将数据直接传递给内核缓冲区,fork 不会复制这一缓冲区。

相关文章:

板凳----Linux/Unix 系统编程手册 25章 进程的终止

25.1 进程的终止&#xff1a;_exit()和exit() 440 1. _exit(int status)&#xff0c; status 定义了终止状态&#xff0c;父进程可调用 wait 获取。仅低8位可用&#xff0c;调用 _exit() 总是成功的。 2.程序一般不会调用 _exit()&#xff0c; 而是调用库函数 exit()。exit() …...

若依Ruoyi-vue和element admin的区别,该如何选择。

提到中后台的前端框架&#xff0c;每个人都能列举出很多&#xff0c;这其中提及率比较高的就是Ruoyi和element admin两款&#xff0c;很多小伙伴分不清二者&#xff0c;本文为大家详细讲解一下。 一、若依Ruoyi-vue是什么&#xff1f; 若依Ruoyi-Vue是一款基于 Vue.js 开发的…...

Sklearn之朴素贝叶斯应用

目录 sklearn中的贝叶斯分类器 前言 1 分类器介绍 2 高斯朴素贝叶斯GaussianNB 2.1 认识高斯朴素贝叶斯 2.2 高斯朴素贝叶斯建模案例 2.3 高斯朴素贝叶斯擅长的数据集 2.3.1 三种数据集介绍 2.3.2 构建三种数据 2.3.3 数据标准化 2.3.4 朴素贝叶斯处理数据 2.4 高斯…...

网络编程(二)TCP编程 TCP粘包问题

文章目录 一、TCP网络编程&#xff08;一&#xff09;流程&#xff08;二&#xff09;相关函数1. socket2. bind3. listen4. accept5. connect 二、收发函数&#xff08;一&#xff09;send函数&#xff08;二&#xff09;recv函数 三、TCP粘包问题&#xff08;一&#xff09;将…...

【总线】AXI总线:FPGA设计中的通信骨干

目录 AXI4&#xff1a;高性能地址映射通信的基石 AXI4-Lite&#xff1a;轻量级但功能强大的通信接口 AXI4-Stream&#xff1a;高速流数据传输的利器 结语&#xff1a;AXI总线在FPGA设计中的重要性 大家好,欢迎来到今天的总线学习时间!如果你对电子设计、特别是FPGA和SoC设计…...

Cesium源码解析六(3dtiles属性获取、建筑物距离计算、建筑物着色及其原理分析)

快速导航 Cesium源码解析一&#xff08;搭建开发环境&#xff09; Cesium源码解析二&#xff08;terrain文件的加载、解析与渲染全过程梳理&#xff09; Cesium源码解析三&#xff08;metadataAvailability的含义&#xff09; Cesium源码解析四&#xff08;metadata元数据拓展…...

AI 情感聊天机器人之旅 —— 相关论文调研

开放域闲聊场景 Prompted LLMs as Chatbot Modules for Long Open-domain Conversation 发布日期&#xff1a;2023-05-01 简要介绍&#xff1a;作者提出了 MPC&#xff08;模块化提示聊天机器人&#xff09;&#xff0c;这是一种无需微调即可创建高质量对话代理的新方法&…...

WPF Prism框架搭建

WPF Prism框架搭建 1.引入Prism框架 在Nuget包管理器中搜索Prism&#xff0c;并添加到项目中 2.在项目中使用prism框架 2.1 修改app.xaml 删除项目中自带的StartupUri 修改Application节点为prism:PrismApplication 引入prism命名空间 <prism:PrismApplication x:C…...

MyBatisplus使用报错--Invalid bound statement

报错如下 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.lotus.mybatis.mapper.UserMapper.selectListat org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235)at com.baomidou.mybatisplus.cor…...

QT-QPainter实现一个动态充电的电池

1、效果 2、核心代码 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer>...

【云原生】Kubernetes----Metrics-Server组件与HPA资源

目录 引言 一、概述 &#xff08;一&#xff09;Metrics-Server简介 &#xff08;二&#xff09;Metrics-Server的工作原理 &#xff08;三&#xff09;HPA与Metrics-Server的作用 &#xff08;四&#xff09;HPA与Metrics-Server的关系 &#xff08;五&#xff09;HPA与…...

模拟原神圣遗物系统-小森设计项目,设计圣遗物(生之花,死之羽,时之沙,空之杯,理之冠)抽象类

分析圣遗物 在圣遗物系统&#xff0c;玩家操控的是圣遗物的部分 因此我们应该 物以类聚 人与群分把每个圣遗物的部分&#xff0c;抽象出来 拿 生之花&#xff0c;死之羽为例 若是抽象 类很好的扩展 添加冒险家的生之花 时候继承生之花 并且名称冒险者- 生之花 当然圣遗物包含…...

仿真模拟--telnet服务两种认证模式(自作)

自己做的笔记,有问题或看不懂请见解一下~ 目录 两个路由器间实现telnet服务(password认证模式) server client 两个路由器间实现telnet服务(aaa认证模式) server client 改名 tab键补齐 不会就扣问号 ? save 两个路由器间实现telnet服务…...

Apple Phone Memory

Apple Phone Memory 苹果手机内存查询&#xff0c;哪些应用程序&#xff08;app&#xff09;占用内存&#xff1a; 设置 通用 iPhone储存空间 清理下QQ音乐&#xff1a;...

Kubernetes容器运行时:Containerd vs Docke

容器化技术笔记 Kubernetes容器运行时&#xff1a;Containerd vs Docke - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this arti…...

【java 线程的状态】

介绍 Java 线程在运⾏的⽣命周期中的指定时刻只可能处于下⾯ 6 种不同状态的其中⼀个状态 状态名称说明NEW初始状态,线程被构建,但是还没有调用start()方法RUNNABLE运行状态,Java线程将操作系统中的就绪和运行两种状态统称为"运行中"BLOCKED阻塞状态,表示线程阻塞于…...

php加密验签

签名生成步骤&#xff08;小程序端/前端&#xff09;&#xff1a; 确定参与签名的参数&#xff1a;选择需要参与签名的请求参数&#xff0c;通常包括请求的时间戳、随机数、请求的数据等。 参数排序与拼接&#xff1a;将所有参与签名的参数按照字母顺序排序&#xff0c;并拼接成…...

【Golang - 90天从新手到大师】Day06 - 数组

系列文章合集 Golang - 90天从新手到大师 数组是golang中最常用的一种数据结构,数组就是同一类型数据的有序集合 定义一个数组 格式: var name [n]type n为数组长度,n>0 且无法修改,type为数组的元素类型如: var a [2]int上面的例子定义了一个长度为2,元素类型为int的数组…...

java的有参构造方法

java的有参构造方法和无参构造方法类似&#xff0c;区别是构造方法名称里后面跟着一个括号&#xff0c;括号里是参数的定义 示例代码如下 class student4{private String name;private int age;public student4(String n,int a) {namen;agea;System.out.println("调用了…...

Vue66-vue-默认插槽

一、默认插槽需求 1-1、原本的写法&#xff1a; 在每个category组件中用v-show来做条件渲染&#xff0c;但是不方便&#xff01; 1-2、默认插槽 img标签&#xff0c;ul标签&#xff0c;video标签&#xff0c;都是在app组件中完成解析之后&#xff0c;塞到category组件中的&…...

tsf-consul的使用

在腾讯云微服务平台TSF中使用Consul作为服务发现组件,通常需要遵循以下步骤: ### 1. 创建应用 首先,您需要在TSF控制台创建一个应用。在创建应用时,选择合适的业务类型、开发语言、开发框架等信息。对于使用Consul作为服务发现组件的Spring Cloud应用,您需要选择“业务应…...

【perl】基本语法 /备忘录/

分享 perl 语言学习资源 Perl 教程|极客教程 (geek-docs.com) Perl [zh] (runebook.dev) Perl 运算符 | 菜鸟教程 (runoob.com) Perl Documentation - Perldoc Browser Search the CPAN - metacpan.org 当然还有一些经典书籍&#xff0c;不再列举。 1、数字 1.1、数字表…...

mongodb 集群安装

整体架构图&#xff1a; 1. 配置域名 Server1&#xff1a; OS version: CentOS Linux release 8.5.2111 hostnamectl --static set-hostname mongo01 vi /etc/sysconfig/network # Created by anaconda hostnamemong01 echo "192.168.88.20 mong1 mongo01.com mongo…...

绿茶集团重启IPO:流量渐退、业绩波动,还能讲出好故事吗?

近日&#xff0c;绿茶集团有限公司(下称“绿茶集团”)向港交所递交上市申请&#xff0c;花旗、招银国际为其联席保荐人。 回望绿茶集团的上市之路&#xff0c;可谓有诸多坎坷。该公司于2021年3月首度向港交所发起冲击&#xff0c;但却将中文版招股书中的“流动负债总额”错写成…...

Git与SSH

Git Git是一种分布式版本控制系统&#xff0c;最初由Linus Torvalds为管理Linux内核开发而设计并开发。Git可以帮助开发团队协作管理代码&#xff0c;跟踪代码变更历史&#xff0c;并在需要时回溯到特定版本。 分布式版本控制&#xff1a;每个开发者都可以拥有完整的代码仓库…...

我的创作纪念日--码农阿豪

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…...

Git 学习笔记(超详细注释,从0到1)

Git学习笔记 1.1 关键词 Fork、pull requests、pull、fetch、push、diff、merge、commit、add、checkout 1.2 原理&#xff08;看图学习&#xff09; 1.3 Fork别人仓库到自己仓库中 记住2个地址 1&#xff09;上游地址&#xff08;upstream地址&#xff09;&#xff1a;http…...

GitLab项目组相关操作(创建项目组Group、创建项目组的项目、为项目添加成员并赋予权限)

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。 君不见,黄河之水天上来,奔流到海不复回。 君不见,高堂明镜悲白发,朝如青丝暮成雪。 ——《将…...

英语恶补ing

ing的词组都有停下来做某事的感觉了。 second hand是形容词了。 wouldnt buy这里的would是情态动词&#xff0c;也是助动词 助动词不能单独使用&#xff0c;要搭配实义动词&#xff0c;这样才能构成谓语 情态动词&#xff08;modals&#xff09;在英语中有多种作用&#xff…...

DS1339C串行实时时钟-国产兼容RS4C1339

RS4C1339串行实时时钟是一种低功耗的时钟/日期设备&#xff0c;具有两个可编程的一天时间报警器和一个可编程方波输出。地址和数据通过2线双向总线串行传输。时钟/日期提供秒、分钟、小时、天、日期、月份和年份信息。对于少于31天的月份&#xff0c;月末的日期会自动调整&…...

淘宝客做网站推广赚钱吗/互联网营销推广

在网络上给自己安个家&#xff0c;或许是不少人的愿望。这需要有两个前提条件&#xff0c;第一需要有个靠谱的免费空间&#xff0c;第二&#xff0c;如果想使用自己独立域名的话&#xff0c;需要自己申请一个域名&#xff0c;然后空间需要支持绑定独立域名。sourceforge.net提供…...

兰溪优秀高端网站设计地址/发广告推广平台

本文讲的是许给云存储一个未来&#xff0c;【IT168 资讯】在IT行业中&#xff0c;许多厂商正在不断推出创新的托管解决方案。  一些厂商是通过市场宣传语言来吸引你的眼球&#xff0c;一些厂商则用是新方式来解决旧问题。但是作为一名负责的IT人员&#xff0c;你确实需要注意…...

wordpress不锈钢企业/策划营销推广方案

文章目录&#x1f3aa; 模板初阶&#x1f680;1.泛型编程&#x1f680;2.函数模板&#x1f680;3.类模板&#x1f3aa; 内存管理&#x1f680;1.C/C内存分布&#x1f680;2.C/C内存管理⭐2.1 C语言内存管理⭐2.2 C内存管理方式&#x1f680;3.new & delete的实现原理&#…...

wordpress首页音乐/危机公关

了解MySQL(超详细的MySQL工作原理 体系结构)1.MySQL体系结构2.MySQL内存结构3.MySQL文件结构4.innodb体系结构一、了解MySQL前你需要知道的引擎是什么:MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并…...

长沙公司网站的建设/北京网络seo

您的“关注”和“点赞”&#xff0c;是信任&#xff0c;是认可&#xff0c;是支持&#xff0c;是动力...... 如意见相佐&#xff0c;可留言。 本人必将竭尽全力试图做到准确和全面&#xff0c;终其一生进行修改补充更新。1 元组概述 元组是由一系列按特定顺序排序的元素组成的序…...

淘客帝国 wordpress/爱站seo工具包官网

这是 利用Excel学习Python 系列的第8篇文章想用一个完整的案例讲解Python数据分析的整个流程和基础知识&#xff0c;实际上以一个数据集为例&#xff0c;数据集是天池上的一个短租数据集&#xff0c;后台回复&#xff1a;短租数据集&#xff0c;即可获得。先来想一下数据分析的…...