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

linxu学习之进程

文章目录

  • 进程
    • 程序和进程
    • 产生进程
    • 销毁进程
    • 多进程高并发设计
    • 孤儿僵尸守护进程
      • 孤儿进程:
      • 守护进程(重点)
    • 僵尸进程:

进程

程序和进程

操作系统可以运行多个程序,那他是如何运行的?实际上,CPU的执行是很快的,而待运行的程序很多,那么为了让操作系统运行多个程序,CPU会把它的执行时间划分成很多段,比如每一段是0.1秒,那么就可以这样A程序运行0.1秒,然后B程序运行0.1,然后C程序运行0.2秒,因为这个切换很快,所以我们感觉程序是同时运行的。

产生进程

  • 创建进程很简单,直接调用fork函数:pid_t fork(void);

创建进程用法举例:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(){int pid = 0;// 父子进程不共享局部变量// pid_t fork(void);pid_t fpid = fork(); // fpid表示fork函数返回的值if(fpid < 0){printf("创建子进程失败\n");return fpid;}else if(fpid == 0){// 创建成功后子进程中fpid == 0pid = getpid();printf("子进程,子进程pid = %d\n",getpid());}else if(fpid > 0){// 创建成功后父进程的fpid 为子进程的pidpid = getpid();printf("父进程,父进程pid = %d\n",getpid());printf("父进程,子进程pid = %d\n",getpid());}// 再创建3个子进程用于观察for(int i = 3 ; i > 0 && fpid > 0 ; i--){fpid = fork();}printf("pid = %d\n",pid);while (1);return 0;
}

在这里插入图片描述

调用fork函数后,会创建一个子进程,并且父子两个进程都从fork处执行,fork函数有两个返回值,对于父进程会返回子进程的pid,此时pid会大于0,对于子进程来说,pid会等于0。

局部变量:写时复制,读时共享

销毁进程

exit - 终止正在执行的进程

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>int main()
{int pid = 0;// pid_t fork(void);pid_t fpid = fork();if (fpid < 0){printf("创建子进程失败\n");return fpid;}else if (fpid == 0){printf("我是子进程,马上就要exit了\n");exit(-1);printf("子进程还活着\n");}else if (fpid > 0){printf("父进程还活着\n");}while (1);return 0;
}

这里子进程已经退出,但是父进程没有执行完毕,导致子进程没有回收变成僵尸进程
在这里插入图片描述

多进程高并发设计

在这里插入图片描述
优点:

  • 若要用多进程实现高并发那么自己linxu系统cpu有多少核,就产生多少个进程多个核可以并发执行只有多个进程在不同的核上运行才可以充分利用多核系统的并发处理能力

  • 比如:cpu为四核,那么主进程就产生4个子进程,让四个子进程分别在不同的核上运行,

  • 4个子进程在工作的时候,把任务放在一个共享内存中(通过内存映射,使多个进程可以访问一个内存),哪个任务做完了,就接着拿任务给每个子进程的负载均衡

  • 职责明确:父进程管理生死,子进程工作

查看cpu核数

cat /proc/cpuinfo
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>typedef void (*spawn_proc_pt)(void *data);
static void worker_process_cycle(void *data);
static void start_worker_processes(int n);
pid_t spawn_process(spawn_proc_pt proc, void *data, char *name);int main(int argc, char **argv)
{// 子进程用于工作,父进程用于管理子进程// 开启工作进程,创建4个子进程start_worker_processes(4);// 管理子进程wait(NULL);
}// 开启工作进程
void start_worker_processes(int n)
{int i = 0;for (i = n - 1; i >= 0; i--){// 创建子进程spawn_process(worker_process_cycle, (void *)(intptr_t)i, "worker process");}
}// 创建子进程
// spawn_proc_pt 类型的函数:void worker_process_cycle(void *data)
pid_t spawn_process(spawn_proc_pt proc, void *data, char *name)
{pid_t pid;pid = fork(); // 创建子进程switch (pid){case -1:fprintf(stderr, "fork() failed while spawning \"%s\"\n", name);return -1;case 0:proc(data); // 成功创建子进程后让子进程去工作return 0;default:break;}printf("start %s %ld\n", name, (long int)pid);return pid;
}// 给进程安排工作
void worker_process_cycle(void *data)
{// data 其实是一个int*类型int worker = (intptr_t)data;// 初始化worker_process_init(worker);// 干活for (;;){sleep(10);printf("pid %ld ,doing ...\n", (long int)getpid());}
}// 初始化进程
void worker_process_init(int worker)
{cpu_set_t cpu_affinity;// worker = 2;// 多核高并发处理  4core  0 - 0 core 1 - 1  2 -2 3 -3CPU_ZERO(&cpu_affinity); // 结构体清零// CPU_SETSIZE:1024 支持cpu最大的数量CPU_SET(worker % CPU_SETSIZE, &cpu_affinity); // 0 1 2 3 设置核/*在多CPU系统中,通过sched_setaffinity ()可以设置进程的CPU亲和力,使进程绑定在某一个或几个CPU上运行,避免在CPU之间来回切换,从而提高该进程的实时性能。*/if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_affinity) == -1){fprintf(stderr, "sched_setaffinity() failed\n");}
}

查看进程对应的核数
在这里插入图片描述

代码中函数指针不太理解的看看下方代码:

// typedef  返回类型(*新类型)(参数表)
typedef char (*PTRFUN)(int); 
PTRFUN pFun; 
char glFun(int a){ return;} 
void main() 
{ pFun = glFun; (*pFun)(2);  //调用函数
} 

查看进程在cpu的核上执行的命令: ps -eLo ruser,pid,lwp,psr,args

孤儿僵尸守护进程

孤儿进程:

一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程所收养,并由init进程对它们完成状态收集工作。
想想我们如何模仿一个孤儿进程? 答案是: kill 父进程!

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(){int fpid = 1;// 父子进程不共享局部变量for(int i = 5 ; i > 0 && fpid > 0 ; i--){fpid = fork();}if(fpid < 0){printf("创建子进程失败\n");return fpid;}else if(fpid == 0){while(1);}else if(fpid > 0){while(1);}return 0;
}

在这里插入图片描述

守护进程(重点)

把孤儿进程做成守护进程

不与任何终端关联的进程,通常情况下守护进程在系统启动时就在运行,它们以root用户或者其他特殊用户(apache和postfix)运行,并能处理一些系统级的任务。守护进程脱离于终端,是为了避免进程在执行过程中的信息在任何终端上显示,并且进程也不会被任何终端所产生的终端信息所打断(比如关闭终端等)。那如何成为一个守护进程呢? 步骤如下:

  • 1.调用fork(),创建新进程,它会是将来的守护进程.
  • 2.在父进程中调用exit(父进程挂掉),保证子进程不是进程组长
  • 3.调用setsid()创建新的会话区 – 具体先不追究
  • 4.将当前目录改成根目录(如果把当前目录作为守护进程的目录,当前目录不能被卸载他作为守护进程的工作目录)
  • 5.将标准输入,标准输出,标准错误重定向到/dev/null.
    我们来看这个代码:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>// 一般传入 0 , 0
int daemon(int nochdir, int noclose)
{int fd = 0;switch (fork()){case -1:return (-1);case 0:break;default:_exit(0); // 父进程自杀}if (setsid() == -1) // 创建会画return (-1);if (!nochdir) // 将当前目录改成根目录(void)chdir("/");if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1){// 重定向 标准输入 标准输出 标准出错(void)dup2(fd, STDIN_FILENO);(void)dup2(fd, STDOUT_FILENO);(void)dup2(fd, STDERR_FILENO);if (fd > 2)(void)close(fd);}return (0);
}int main()
{// 创建子进程,并且把父进程杀死daemon(0,0);printf("hello\n");while(1);// 处理事务return 0;
}

父进程自杀后,守护进程 init 接管 , 一直在后台进行运行
在这里插入图片描述

僵尸进程:

一个进程使用fork创建子进程,如果子进程退出(exit),而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。

  1. 僵尸进程怎样产生的:
  • 一个进程使用fork创建子进程,如果子进程退出(exit),而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
  • 它需要它的父进程来为它收尸,如果他的父进程没安装 SIGCHLD信号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,那么它就一直保持僵尸状态,如果这时父进程结束了, 那么init进程自动会接手这个子进程,为它收尸,它还是能被清除的。

1.怎么查看僵尸进程:
  利用命令ps,可以看到有标记为的进程就是僵尸进程。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>int main(){pid_t fpid = fork();if(fpid < 0){printf("创建子进程失败\n");return fpid;}else if(fpid == 0){exit(-1);}else if(fpid > 0){while(1);}return 0;
}

这里可以用 wait 和 waitpid 函数回收子进程
在这里插入图片描述
2.怎样来清除僵尸进程:

  • 改写父进程,在子进程死后要为它收尸。具体做法是接管SIGCHLD信号。子进程死后,会发送SIGCHLD信号给父进程,父进程收到此信号后,执行waitpid()函数为子进程收尸。这是基于这样的原理:就算父进程没有调用 wait,内核也会向它发送SIGCHLD消息,尽管对默认处理是忽略,如果想响应这个消息,可以设置一个处理函数。
  • 把父进程杀掉。父进程死后,僵尸进程成为"孤儿进程",过继给1号进程init,init始终会负责清理僵尸进程。它产生的所有僵尸进程也跟着消失。

相关文章:

linxu学习之进程

文章目录进程程序和进程产生进程销毁进程多进程高并发设计孤儿僵尸守护进程孤儿进程&#xff1a;守护进程(重点)僵尸进程&#xff1a;进程 程序和进程 操作系统可以运行多个程序&#xff0c;那他是如何运行的&#xff1f;实际上&#xff0c;CPU的执行是很快的&#xff0c;而待…...

蓝桥杯真题2

[蓝桥杯 2013 省 B] 连号区间数 题目描述 小明这些天一直在思考这样一个奇怪而有趣的问题&#xff1a; 在 111 ~ NNN 的某个全排列中有多少个连号区间呢&#xff1f;这里所说的连号区间的定义是&#xff1a; 如果区间 [L,R][L, R][L,R] 里的所有元素&#xff08;即此排列的…...

PWM互补输出,以及死区时间计算

本文基于野火例程进行解说 实验内容 本次实验输出一对互补的pwm波&#xff0c;且进行死区时间的计算说明。 代码 互补输出对应的定时器初始化代码&#xff1a; bsp_advance_tim.c /********************************************************************************* fi…...

基于深度学习的海洋动物检测系统(Python+YOLOv5+清新界面)

摘要&#xff1a;基于深度学习的海洋动物检测系统使用深度学习技术检测常见海洋动物&#xff0c;识别图片、视频和实时视频中的海洋动物&#xff0c;方便记录、展示和保存结果。本文详细介绍海洋动物检测系统&#xff0c;在介绍算法原理的同时&#xff0c;给出Python的实现代码…...

C# 计算方差

50&#xff0c;100&#xff0c;100&#xff0c;60&#xff0c;50 计算他们的方差 为了计算这些数的方差&#xff0c;需要进行以下步骤&#xff1a; 1. 计算平均值&#xff0c;即将这些数相加&#xff0c;然后除以它们的数量。 平均值 (50 100 100 60 50) / 5 72 2. 计…...

HJZS电源监视继电器HJZS-E202 AC220V

系列型号&#xff1a; HJZS-E202断电延时继电器 HJZS-E002断电延时继电器 一 应用 HJZS-E202电源监视继电器用于直流或交流操作的各种保护和自动控制的装置中&#xff0c;用以增加触点数量。 二 安装结构 导轨安装9壳体结构&#xff0c;具体尺寸参阅外型尺寸图。 三 产品型号…...

dolphinscheduler 2.0.6 资源中心改造方案二:通过NFS挂载共享目录

目录调度资源中心存储概要安装NFS服务器客户端调度验证关闭SFTP开关&#xff08;可忽略&#xff09;重新上传资源文件worker执行任务验证服务器woker客户端worker其它nfs共享目录的配置文件/etc/exports说明调度资源中心存储概要 针对现有的单机存储可以做哪些扩展&#xff1f;…...

基于集成学习的用户流失预测并利用shap进行特征解释

基于集成学习的用户流失预测并利用shap进行特征解释 小P&#xff1a;小H&#xff0c;如果我只想尽可能的提高准确率&#xff0c;有什么好的办法吗&#xff1f; 小H&#xff1a;优化数据、调参侠、集成学习都可以啊 小P&#xff1a;什么是集成学习啊&#xff0c;听起来就很厉害的…...

【Java版oj 】 day17杨辉三角形的变形、计算某字符出现次数

目录 一、杨辉三角形的变形 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代码 二、计算某字符出现次数 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代…...

智能驾驶芯片赛道混战:如何看待5类玩家的竞争格局?

智能驾驶芯片赛道&#xff0c;一直是业内关注的焦点。 高工智能汽车注意到&#xff0c;针对L0-L2&#xff0c;业内基本采用智能前视一体机&#xff08;IFC&#xff09;方案&#xff1b;要实现高速NOA、城市NOA等更为高阶的智驾功能等&#xff0c;则基本采用域控制器方案。从IF…...

vue antd table表格的增删改查(三)input输入框根据关键字模糊查询【后台管理系统 使用filter与indexOf嵌套】

vue antd table表格的增删改查&#xff08;三&#xff09;input输入框根据关键字查询【后台管理系统filter与indexOf嵌套】知识回调场景复现利用filter和indexOf方法实现模糊查询1.查询对象为单层的数组元素2.查询对象为多层的数组元素&#xff08;两层为例&#xff09;3.查询对…...

【计组】性能指标——速度

衡量计算机性能的指标之一——速度&#xff0c;是指计算机执行完所有指令所耗费时间的长短。 一、概念&#xff1a; 引出了如下概念&#xff1a;机器字长&#xff1a;指计算机一次能处理的二进制位数&#xff0c;也就是我们通常说的32位64位计算机中的位。 机器字长决定了计算…...

【PC自动化测试-4】inspect.exe 详解

1&#xff0c;inspect.exe图解" 检查 "窗口有几个主要部分&#xff1a;● 标题栏。 显示" 检查 HWND (窗口句柄) 。● 菜单栏。 提供对 检查功能 的访问权限。● 工具 栏。 提供对 检查功能 的访问权限。● 树视图。 将 UI 元素的层次结构呈现为树视图控件&…...

比肩ChatGPT的国产AI:文心一言——有话说

&#x1f517; 运行环境&#xff1a;chatGPT&#xff0c;文心一言 &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&am…...

【第13届蓝桥杯】C/C++组B组省赛题目+详解

A.九进制转十进制 题目描述 九进制正整数(2022)9转换成十进制等于多少&#xff1f; 解&#xff1a; 2*9^02*9^12*9^321814581478; B.顺子日期 题目描述 小明特别喜欢顺子。顺子指的就是连续的三个数字&#xff1a;123、456等。顺子日期指的就是在日期的yyyymmdd表示法中&a…...

STM32 KEI 调试新手注意事项

记录一下解决问题的经过:1&#xff0c;用STM32 cubeMX 生成的MKD工程,默认的代码优化级别是level3 &#xff0c; 这个级别 会把一些代码给优化掉&#xff0c;造成一些意想不到的结果&#xff0c;最直观的就是 被优化的语句不能打断点调试&#xff0c;当你打了断点 &#xff0c;…...

Windows权限提升—令牌窃取、UAC提权、进程注入等提权

Windows权限提升—令牌窃取、UNC提权、进程注入等提权1. 前言2. at本地命令提权2.1. 适用范围2.2. 命令使用2.3. 操作步骤2.3.1. 模拟提权2.3.2. at配合msf提权2.3.2.1. 生成木马文件2.3.2.2. 设置监听2.3.2.3. 设置反弹2.3.2.4. 查看反弹效果3. sc本地命令提权3.1. 适用范围3.…...

不做孔乙己也不做骆驼祥子

对教书育人的探讨前言一、为什么要“育人”1.育人为先2.育人是快乐的二、怎么“育人”前言 借着本次师德师风建设的主题&#xff0c;跟各位老师谈一谈对于“育人”的一些观点&#xff0c;和教育的一些看法。本文仅代表自己的观点&#xff0c;有不到位的地方&#xff0c;大家可以…...

ChatGPT原理解析

文章目录Transformer模型结构构成组件整体流程GPT预训练微调模型GPT2GPT3局限性GPT4相关论文Transformer Transformer&#xff0c;这是一种仅依赖于注意力机制而不使用循环或卷积的简单模型&#xff0c;它简单而有效&#xff0c;并且在性能方面表现出色。 在时序模型中&#…...

常用算法实现【必会】:sort/bfs/dfs

文章目录常用排序算法实现&#xff08;Go版本&#xff09;BFS 广度优先遍历&#xff0c;利用queueDFS 深度优先遍历&#xff0c;利用stack前序遍历&#xff08;根 左 右&#xff09;中序遍历&#xff08;左根右&#xff09;后序遍历&#xff08;左 右 根&#xff09;BFS/DFS 总…...

瑟瑟发抖吧——用了这款软件,我的开发效率提升了50%

一、前言 开发中&#xff0c;一直听到有人讨论是否需要重复造轮子&#xff0c;我觉得有能力的人&#xff0c;轮子得造。但是往往开发周期短&#xff0c;用轮子所节省的时间去更好的理解业务&#xff0c;应用到业务中&#xff0c;也能清晰发现轮子的利弊&#xff0c;一定意义上…...

笔记本只使用Linux是什么体验?

个人主页&#xff1a;董哥聊技术我是董哥&#xff0c;嵌入式领域新星创作者创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01;近期&#xff0c;也有朋友问我&#xff0c;笔记本只安装Linux怎么样&#xff0c;刚好我也借此来表达一下我的感受…...

pipeline业务发布

业务环境介绍公司当前业务上线流程首先是通过nginx灰度&#xff0c;dubbo-admin操作禁用&#xff0c;然后发布上线主机&#xff0c;发布成功后&#xff0c;dubbo-admin启用&#xff0c;nginx启用主机&#xff1b;之前是通过手动操作&#xff0c;很不方便&#xff0c;本次优化为…...

【巨人的肩膀】JAVA面试总结(七)

&#x1f4aa;MyBatis 1、谈谈你对MyBatis的理解 Mybatis是一个半ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;它内部封装了JDBC&#xff0c;加载驱动、创建连接、创建statement等繁杂的过程&#xff0c;开发者开发时只需要关注如何编写SQL语句&#xff0c;可以…...

Python满屏表白代码

目录 前言 爱心界面 无限弹窗 前言 人生苦短&#xff0c;我用Python&#xff01;又是新的一周啦&#xff0c;本期博主给大家带来了一个全新的作品&#xff1a;满屏表白代码&#xff0c;无限弹窗版&#xff01;快快收藏起来送给她吧~ 爱心界面 def Heart(): roottk.Tk…...

Spring学习流程介绍

Spring学习流程介绍 Spring技术是JavaEE开发必备技能&#xff0c;企业开发技术选型命中率>90%; Spring有下面两大优势: 简化开发: 降低企业级开发的复杂性 框架整合: 高效整合其他技术&#xff0c;提高企业级应用开发与运行效率 Spring官网: https://spring.io/ Spring发展…...

杭银消金基于 Apache Doris 的统一数据查询网关改造

导读&#xff1a; 随着业务量快速增长&#xff0c;数据规模的不断扩大&#xff0c;杭银消金早期的大数据平台在应对实时性更强、复杂度更高的的业务需求时存在瓶颈。为了更好的应对未来的数据规模增长&#xff0c;杭银消金于 2022 年 10 月正式引入 Apache Doris 1.2 对现有的风…...

Flink学习笔记(六)Time详解

一、Flink中Time的三种类型&#xff1a; Stream数据中的Time&#xff08;时间&#xff09;分为以下3种&#xff1a; 1.Event Time&#xff08;事件产生的时间&#xff09;&#xff1a; 事件的时间戳&#xff0c;通常是生成事件的时间。Event time 是事件本身的时间&#xff0c…...

「Vue面试题」在项目中你是如何解决跨域的?

文章目录一、跨域是什么二、如何解决CORSProxy一、跨域是什么 跨域本质是浏览器基于同源策略的一种安全手段 同源策略&#xff08;Sameoriginpolicy&#xff09;&#xff0c;是一种约定&#xff0c;它是浏览器最核心也最基本的安全功能 所谓同源&#xff08;即指在同一个域&…...

java八股文--数据库

数据库1.索引的基本原理2.聚簇和非聚簇索引的区别3.mysql索引的数据结构以及各自的优劣4.索引的设计原则5.事务的基本特性和隔离级别6.mysql主从同步原理7.简述MyISAM和InnoDB的区别8.简述mysql中索引类型及对数据库性能的影响9.Explain语句结果中各个字段分别表示什么10.索引覆…...

怎么做动态网站页面/百度上做优化

类似py2exe软件真的能保护python源码吗 背景 最近写了个工具用于对项目中C/C文件的字符串常量进行自动化加密处理&#xff0c;用python写的&#xff0c;工具效果不错&#xff0c;所以打算在公司内部推广。为了防止代码泄露就考虑不采用直接给源码方式&#xff0c;而python二进制…...

asp绿色简洁通用型企业网站源码/百度seo搜索引擎优化培训

点击下载 FileDown.zip 主要功能如下 1.参数为虚拟路径 2.获取物理地址 3.普通下载 4.分块下载 5.输出硬盘文件&#xff0c;提供下载 支持大文件、续传、速度限制、资源占用小 看下面代码吧 /// <summary> /// 编 码 人&#xff1a;苏飞 /// 联系方式&#xff1a;3619836…...

合肥微网站建设/seo搜索引擎优化培训班

支持安卓9哦 无root党不进来看看吗更新安卓9后&#xff0c;相信大家的平行空间都会闪退吧 是不是很烦恼呢 我分享的这个平行空间精简版是最新版的&#xff0c;支持安卓9 不会闪退&#xff0c;本人米8 安卓9完美运行&#xff0c;新人发帖不关照一下吗[应用名称]: 平行空间精简版…...

网站建设蓝色工匠/成都排名推广

2019独角兽企业重金招聘Python工程师标准>>> yum remove mysql mysql-server mysql-libs compat-mysql51 rm -rf /var/lib/mysql rm /etc/my.cnf 查看是否还有mysql软件&#xff1a; rpm -qa|grep mysql 有的话继续删除 转载于:https://my.oschina.net/hycx227/blog…...

网站建设项目描述范文/百度如何收录网站

解决微信浏览器内video全屏问题参考文章&#xff1a; &#xff08;1&#xff09;解决微信浏览器内video全屏问题 &#xff08;2&#xff09;https://www.cnblogs.com/phpjinggege/p/8270742.html 备忘一下。...

中国建设银行招标网站/企业营销策划合同

前几天在读者群里&#xff0c;大家针对看书好、还是看视频好、还是自学好&#xff0c;展开了激烈的讨论&#xff0c;场面一度失控。作为群主的我&#xff0c;为了缓和气氛&#xff0c;选择了和稀泥&#xff0c;我说都好&#xff0c;并且拿我自己举了例子。说着说着我发现&#…...