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

企业宣传网站建设重庆网站推广联系方式

企业宣传网站建设,重庆网站推广联系方式,栾城做网站,住房和城乡建设部办公厅🥁作者: 华丞臧. 📕​​​​专栏:【LINUX】 各位读者老爷如果觉得博主写的不错,请诸位多多支持(点赞收藏关注)。如果有错误的地方,欢迎在评论区指出。 推荐一款刷题网站 👉 LeetCode刷题网站 文…

🥁作者华丞臧.
📕​​​​专栏:【LINUX】
各位读者老爷如果觉得博主写的不错,请诸位多多支持(点赞+收藏+关注)。如果有错误的地方,欢迎在评论区指出。
推荐一款刷题网站 👉 LeetCode刷题网站


文章目录

  • 一、进程替换
    • 1.1 替换原理
    • 1.2 替换函数
  • 二、exec函数
    • 2.1 execl
    • 2.2 execv
    • 2.3 execlp
    • 2.5 execle
    • 2.4 execvp
    • 2.5 execve
  • 补充快捷键
    • 批量化注释
    • 批量化取消注释


一、进程替换

前面我们学习了如何创建子进程,也知道了子进程执行的是父进程的代码片段;那么如果我们想让创建出来的子进程执行全新的程序呢?这时候就需要进程的程序替换。

一般在Linux编程的时候,需要子进程做两类事情:

  1. 让子进程执行父进程的代码片段(服务器代码);
  2. 让子进程执行磁盘中的一个全新的程序,如:shell可以让客户端执行其他人写的代码。

1.1 替换原理

用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。
在这里插入图片描述

程序替换原理总结

  1. 将磁盘中的程序,加载到内存结构;
  2. 重新建立页表映射,谁执行程序替换,就重新建立谁的页表映射效果;让我们的父进程和子进程彻底分离,并让子进程执行一个全新的程序。

注意在程序替换的过程中没有创建新的进程,这个过程指的是程序替换的过程,此时子进程已经创建好了不算新创建的进程。

1.2 替换函数

Linux中有六种exec开头的函数,统称exec函数:
以下六种函数都可以用来进程替换。
在这里插入图片描述

#include <unistd.h>`int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);

函数解释:

  • 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回;
  • 如果调用出错则返回-1。
  • 所以exec函数只有出错的返回值而没有成功的返回值。

命名理解:
这些函数原型看起来很容易混,但只要掌握了规律就很好记。

  • l(list):表示参数采用列表;
  • v(vector):参数用数组
  • p(path):有p自动搜索环境变量PATH;
  • e(env):表示自己维护环境变量;
函数名参数格式是否带路径是否使用当前环境变量
execl列表不是
execlp列表
execle列表不是不是,必须自己组装环境变量
execv数组不是
execvp数组
execve数组不是不是,须自己组装环境变量

二、exec函数

接下来我们挑几个exec函数来说明其使用方式。

2.1 execl

int execl(const char *path, const char *arg, ...);

说明

  • path:程序所在的路径。
  • arg:替换的程序名。
  • ...:可变参数列表,这个我们在使用printf和scanf的时候见过。
  • execl函数替换失败返回-1;

首先使用exec函数之前,我们需要知道如果想执行一个全新的程序,需要做下面两件事:

  1. 找到执行程序路径;
  2. 程序可能携带选项进行执行,也可以不携带;

这里我们可以参照Linux上的命令行是如何使用的,如下:
在这里插入图片描述
Linux中的指令本质上就是程序,所以命令行怎么写我们程序携带选项时传参就怎么写。既然Linux中的指令也是程序,我们首先来试试用指令来替换我们写的程序,代码如下:

#include <stdio.h>
#include <unistd.h>int main()
{printf("进程pid:%d\n", getpid());// arg表示目标程序名,而...参数列表必须以NULL结尾execl("/usr/bin/ls", "ls", NULL); //不带参数//execl("/usr/bin/ls", "ls", "-al", NULL);  //带参数printf("进程替换成功\n");return 0;
}

不带参数的如下图:
在这里插入图片描述
带参数的如下图:
在这里插入图片描述
观察上述两幅图片,我们发现代码中execl下面的那句 printf并没有执行;这是因为一旦替换成功,会将当前进程的代码和数据全部替换了,因此执行完execl函数进程中的代码和数据已经全部被替换了
程序替换函数也有返回值,为int类型;这个返回值不需要判断,一旦进程替换成功就不会有返回值,而替换失败必然会继续向后执行,这个返回值最多让我们知道是什么原因导致替换失败。

使用fork创建子进程,再将子进程进行程序替换,会不会影响父进程呢?

  • 答案是不会,下面我们来实验其过程。
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>int main()
{printf("进程pid:%d\n", getpid());pid_t id = fork();if(id == 0){//childprintf("这是子进程pid:%d,ppid:%d\n", getpid(), getppid());execl("/usr/bin/ls", "ls", "-al", NULL);exit(1);}//parentprintf("这是父进程pid:%d,ppid:%d\n", getpid(), getppid());pid_t ret = waitpid(id, NULL, 0);if(ret > 0) printf("子进程回收成功,ret:%d\n", ret);return 0;
}

在这里插入图片描述
可以看到子进程进行程序替换不会影响父进程,因为进程具有独立性,在数据层面发生写时拷贝:当程序替换的时候,可以理解为代码和数据都发生了写时拷贝,完成了父子进程的分离

2.2 execv

int execv(const char *path, char *const argv[]);

函数说明:

  • path:目标程序的路径;
  • argv:数组用来传参;
  • 替换失败返回-1,其中v表示数组(vector)。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>int main()
{printf("进程pid:%d\n", getpid());pid_t id = fork();if(id == 0){//childprintf("这是子进程pid:%d,ppid:%d\n", getpid(), getppid());// 使用argv进行传参,数组中第一个元素argv[0]必须为目标程序名//argv也必须以NULL结尾//char *const myenv[] = {//    (char*)"ls",//    (char*)"-a",//    (char*)"-l",//    NULL//};char *const myenv[] = {(char*)"pwd",NULL};//execv("/usr/bin/ls", myenv);execv("/usr/bin/pwd", myenv);exit(1);}//parentprintf("这是父进程pid:%d,ppid:%d\n", getpid(), getppid());pid_t ret = waitpid(id, NULL, 0);if(ret > 0) printf("子进程回收成功,ret:%d\n", ret);return 0;
}

在这里插入图片描述
在这里插入图片描述

2.3 execlp

int execlp(const char *file, const char *arg, ...);

函数说明:

  • file:目标程序名;
  • arg:参数,传目标程序名;
  • ...:可变参数列表;
  • 函数命名带p表示可以不带路径,只需要说明目标程序名;系统会通过环境变量PATH查找。
  • 替换失败返回-1。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>int main()
{printf("进程pid:%d\n", getpid());pid_t id = fork();if(id == 0){//childprintf("这是子进程pid:%d,ppid:%d\n", getpid(), getppid()); // 使用execlp,可以不带路径:// 其中两个ls含义不同// 第一个为供系统查找,后面一个加上选项表示如何执行execlp("ls", "ls", "-a", NULL);exit(1);}//parentprintf("这是父进程pid:%d,ppid:%d\n", getpid(), getppid());pid_t ret = waitpid(id, NULL, 0);if(ret > 0) printf("子进程回收成功,ret:%d\n", ret);return 0;
}

在这里插入图片描述

2.5 execle

int execle(const char *path, const char *arg, ...,char *const envp[]);

函数说明:

  • path:目标程序所在路径;
  • arg:参数,传目标程序名;
  • ...:可变参数列表;
  • envp:用户传给目标程序的环境变量;
  • 失败返回-1。

使用exec函数也可以替换用户自己写的程序:

//replace.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>int main()
{printf("进程pid:%d\n", getpid());pid_t id = fork();if(id == 0){//childprintf("这是子进程pid:%d,ppid:%d\n", getpid(), getppid());char *const env_[] = {(char*)"MYPATH=HELLOWORLD",NULL};execle("./mytest", "mytest", NULL, env_);exit(1);}//parentprintf("这是父进程pid:%d,ppid:%d\n", getpid(), getppid());pid_t ret = waitpid(id, NULL, 0);if(ret > 0) printf("子进程回收成功,ret:%d\n", ret);return 0;
}//mytest.cpp
#include <iostream>
#include <stdlib.h>using namespace std;int main()
{cout << "PATH: " << getenv("PATH") << endl;//cout << "MYPATH: " << getenv("MYPATH") << endl;cout << "hello world1" << endl;cout << "hello world2" << endl;cout << "hello world3" << endl;cout << "hello world4" << endl;cout << "hello world5" << endl;return 0;
}

在这里插入图片描述
如上图,当直接使用execle函数时,进程替换成功了但是运行时进程崩溃了,可以看到此时进程中找不到PATH这个环境变量,那么MYPATH(这是execle函数的传参)呢?

在这里插入图片描述
因此可以得出结论:e的exec函数会添加环境变量给目标进程,执行的是覆盖式的

//这里是使用execl替换代码片段
if(id == 0){//childprintf("这是子进程pid:%d,ppid:%d\n", getpid(), getppid());execl("./mytest", "mytest", NULL);exit(1);}

在这里插入图片描述
使用execl函数PATH环境变量可以正常打印。

如果想要将系统的环境变量保存并且也可以使用用户自己的环境变量,可以使用export指令添加环境变量:

//命令行
export MYPATH="HELLO WORLD"

在这里插入图片描述

2.4 execvp

int execvp(const char *file, char *const argv[]);

函数说明:

  • file:目标程序名;
  • argv:按照命令行参数格式统一将程序名和选项字符串放入数组中;
  • 命名带p表示会使用环境变量PATH。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>int main()
{printf("进程pid:%d\n", getpid());pid_t id = fork();if(id == 0){//childprintf("这是子进程pid:%d,ppid:%d\n", getpid(), getppid());char *const myenv[] = {(char*)"ls",(char*)"-a",(char*)"-l",NULL};execvp("ls", myenv);exit(1);}//parentprintf("这是父进程pid:%d,ppid:%d\n", getpid(), getppid());pid_t ret = waitpid(id, NULL, 0);if(ret > 0) printf("子进程回收成功,ret:%d\n", ret);return 0;
}

在这里插入图片描述

2.5 execve

与其他的exec函数不同的是:execve函数是系统调用接口。

int execve(const char *path, char *const argv[], char *const envp[]);

前面学习的那些exec函数基本都是对系统调用接口直接或者间接的封装,适应与不同的适用场景。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>int main()
{printf("进程pid:%d\n", getpid());pid_t id = fork();if(id == 0){//childprintf("这是子进程pid:%d,ppid:%d\n", getpid(), getppid());char *const myenv[] = {(char*)"ls",(char*)"-a",(char*)"-l",NULL};char *const env_[] = {(char*)"MYPATH=HELLOWORLD",NULL};execve("./mytest", myenv, env_);exit(1);}//parentprintf("这是父进程pid:%d,ppid:%d\n", getpid(), getppid());pid_t ret = waitpid(id, NULL, 0);if(ret > 0) printf("子进程回收成功,ret:%d\n", ret);return 0;
}

在这里插入图片描述

补充快捷键

批量化注释

  1. ctrl + v(按一次即可),从需要注释的第一行开始,然后使用HJKL上下左右键选中区域;如果vim被配置过,键盘上的箭头上下左右功能可能改变,因此建议使用HJKL。
    在这里插入图片描述
  2. 切换大写输入I,输入//,再按下Esc就可以完成批量化注释。
    在这里插入图片描述

批量化取消注释

  1. ctrl + v(按一次即可),从需要取消注释的第一行开始,然后使用HJKL上下左右键选中区域;

  2. 输入d就可以完成批量化取消注释。 在这里插入图片描述


文章转载自:
http://dinncosemicontinuum.tpps.cn
http://dinncocodeterminant.tpps.cn
http://dinncotravelog.tpps.cn
http://dinncogodetia.tpps.cn
http://dinncoplumbaginous.tpps.cn
http://dinncoviscoid.tpps.cn
http://dinncoblast.tpps.cn
http://dinncodermonecrotic.tpps.cn
http://dinncoveinstone.tpps.cn
http://dinncobeerburst.tpps.cn
http://dinncowhitewash.tpps.cn
http://dinncorhythmic.tpps.cn
http://dinncochiquita.tpps.cn
http://dinncoxylotomy.tpps.cn
http://dinncohooked.tpps.cn
http://dinncohermit.tpps.cn
http://dinncocolourbreed.tpps.cn
http://dinncocritter.tpps.cn
http://dinncohanker.tpps.cn
http://dinncohellenist.tpps.cn
http://dinncomaniform.tpps.cn
http://dinncolitchi.tpps.cn
http://dinncostewpot.tpps.cn
http://dinncopaleichthyology.tpps.cn
http://dinncodiscommendable.tpps.cn
http://dinncooxidate.tpps.cn
http://dinncoflite.tpps.cn
http://dinncotetrazzini.tpps.cn
http://dinncoplasterwork.tpps.cn
http://dinncocotangent.tpps.cn
http://dinncocolleen.tpps.cn
http://dinncomagazine.tpps.cn
http://dinncopeahen.tpps.cn
http://dinncomisbegot.tpps.cn
http://dinncounpoliced.tpps.cn
http://dinncooft.tpps.cn
http://dinncoswoln.tpps.cn
http://dinncorebuff.tpps.cn
http://dinncoclavel.tpps.cn
http://dinncosiltstone.tpps.cn
http://dinncotrial.tpps.cn
http://dinncorevertible.tpps.cn
http://dinnconeoarsphenamine.tpps.cn
http://dinncodenominal.tpps.cn
http://dinncosculptural.tpps.cn
http://dinncoodra.tpps.cn
http://dinncoineducability.tpps.cn
http://dinncoalgerish.tpps.cn
http://dinncoscrubboard.tpps.cn
http://dinncosafrol.tpps.cn
http://dinncodarg.tpps.cn
http://dinncobowed.tpps.cn
http://dinncolignosulphonate.tpps.cn
http://dinncoechinulate.tpps.cn
http://dinncocommunity.tpps.cn
http://dinncounstockinged.tpps.cn
http://dinncopunchy.tpps.cn
http://dinncoinsert.tpps.cn
http://dinncooriflamme.tpps.cn
http://dinncosurcingle.tpps.cn
http://dinncoclump.tpps.cn
http://dinncoparenthood.tpps.cn
http://dinncoflavone.tpps.cn
http://dinncosymbolism.tpps.cn
http://dinncosurfcaster.tpps.cn
http://dinncotelemachus.tpps.cn
http://dinncomolding.tpps.cn
http://dinncochlortetracycline.tpps.cn
http://dinncospessartite.tpps.cn
http://dinncosarcocarp.tpps.cn
http://dinncoyankeeism.tpps.cn
http://dinncoberth.tpps.cn
http://dinncochatoyance.tpps.cn
http://dinncocitral.tpps.cn
http://dinncomzee.tpps.cn
http://dinncomastoidectomy.tpps.cn
http://dinncocoxitis.tpps.cn
http://dinncoeggwalk.tpps.cn
http://dinncomodena.tpps.cn
http://dinncovulpicide.tpps.cn
http://dinncoinnovator.tpps.cn
http://dinnconaevus.tpps.cn
http://dinncoforestland.tpps.cn
http://dinncosalii.tpps.cn
http://dinncopiedmontite.tpps.cn
http://dinncohemoglobinuric.tpps.cn
http://dinncoisohume.tpps.cn
http://dinncohardiness.tpps.cn
http://dinncocretic.tpps.cn
http://dinncopristine.tpps.cn
http://dinncomurderess.tpps.cn
http://dinncodiplomatise.tpps.cn
http://dinncoallied.tpps.cn
http://dinncotorpidness.tpps.cn
http://dinncobeniseed.tpps.cn
http://dinncocarrolline.tpps.cn
http://dinncokabuki.tpps.cn
http://dinncosnelskrif.tpps.cn
http://dinncocoxsackie.tpps.cn
http://dinncodecile.tpps.cn
http://www.dinnco.com/news/121543.html

相关文章:

  • 广州网站建设及推广长春网站建设技术托管
  • 做视频网站服务器要求吗网站seo优化技能
  • 电白网站建设公司教育机构培训
  • 在哪里推广网站网站入口
  • 网站后期维护内容本地推广平台
  • 无锡网站开发公司电话黄冈网站推广策略
  • 外贸建站用什么服务器人工智能教育培训机构排名
  • 优秀专题网站怎么做平台推广
  • 个人网站建设作用免费的网页入口
  • 网站简繁体转换.rar邵阳做网站的公司
  • 做破解软件网站赚广告费竞价恶意点击犯法吗
  • 深圳建站公司品牌网站建设seo网站优化报价
  • 棋牌游戏在哪做网站专业营销策划团队
  • 网站建设需要的人员百度云登陆首页
  • 西宁高端网站制作首页
  • 医院如何做网站策划点击进入官方网站
  • 响水做网站哪家好推广标题怎么写
  • 江阴外贸网站建设公司网站描述和关键词怎么写
  • 怎么制作手机app及网站收录排名好的发帖网站
  • asp 网站数据库连接错误百度营销登录
  • 做企业门户网站要准备哪些内容2023年9月疫情又开始了吗
  • 国家市场监督管总局官网滁州网站seo
  • 做h5哪个网站好建网站需要什么条件
  • 安贞网站建设2022年关键词排名
  • 郑州网站设计 郑州网站开发太原百度快速排名提升
  • vb .net网站开发市场营销一般在哪上班
  • 网站建设流程分几步seo顾问阿亮
  • 义乌微信网站建设费用大庆黄页查询电话
  • 淘宝刷网站建设2022年新闻摘抄简短
  • 网站主页模板即刻搜索引擎入口