文章目录
创建一批子进程
#include<stdio.h>#include<unistd.h>#include<stdlib.h>#defineN5voidrunChild(){int cnt =10;while(cnt !=0){printf("i am a child : %d , ppid:%d\n",getpid(),getppid());sleep(1);
cnt--;}}intmain(){int i =0;for(; i < N; i++){
pid_t id =fork();if(id ==0){//子进程runChild();exit(0);}//父进程//父进程继续循环}sleep(1000);return0;}
进程终止
进程退出只有三种情况:
代码运行完毕,结果正确。
代码运行完毕,结果不正确
代码异常终止(进程崩溃)
代码异常,本质可能就是代码没有跑完
此时进程的退出码无意义,我们不关心退出码
代码是否正确,统一会采用进程的退出码来进行判断
查看该进程的进程退出码
$?:保存的是最近一次进程退出的时候的退出码
[cxq@iZ7xviiy0goapxtblgih6oZ lesson15]$ echo $?
查看错误码
errno
#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<string.h>#include<errno.h>intmain(){int ret =0;char*p =(char*)malloc(1000*1000*1000*4);if(p ==NULL){//errno 返回的是错误码 ,strerror可以知道错误原因printf("malloc error, %d %s\n", errno,strerror(errno));
ret = errno;}else{printf("malloc success\n");}return ret;}
进程出现异常,本质是我们的进程收到了对应的信号
exit与return的区别
exit在任意地方被调用,都表示调用进程直接退出
return只表示当前函数返回,还会继续向后运行
#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<string.h>#include<errno.h>voidshow(){printf("hello show\n");printf("hello show\n");printf("hello show\n");printf("hello show\n");printf("hello show\n");printf("hello show\n");exit(13);//exit在任意地方被调用,都表示调用进程直接退出,如果此时换成return,return只表示当前函数返回,还会继续向后运行printf("end show\n");printf("end show\n");printf("end show\n");printf("end show\n");printf("end show\n");}intmain(){show();printf("hello Linux\n");return12;}
#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<string.h>#include<errno.h>voidshow(){printf("hello show\n");printf("hello show\n");printf("hello show\n");printf("hello show\n");printf("hello show\n");printf("hello show\n");return;//return只表示当前函数返回,还会继续向后运行exit(13);//exit在任意地方被调用,都表示调用进程直接退出printf("end show\n");printf("end show\n");printf("end show\n");printf("end show\n");printf("end show\n");}intmain(){show();printf("hello Linux\n");return12;}
_exit :
#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<string.h>#include<errno.h>voidshow(){printf("hello show\n");printf("hello show\n");printf("hello show\n");printf("hello show\n");printf("hello show\n");printf("hello show\n");_exit(14);printf("end show\n");printf("end show\n");printf("end show\n");printf("end show\n");printf("end show\n");}intmain(){show();printf("hello Linux\n");return12;}
_exit 与exit的区别
使用exit函数退出进程也是我们常用的方法,exit函数可以在代码中的任何地方退出进程,并且exit函数在退出进程前会做一系列工作
1、执行用户通过atexit或on_exit定义的清理函数。
2、关闭所有打开的流,所有的缓存数据均被写入。
3、调用_exit函数终止进程。
_exit()是系统调用接口,exit()是库函数
当把exit改成_exit时,使用_exit终止进程,不会刷新缓冲区的数据,所以缓冲区当中的数据将不会被输出,就不会看到you can see me 了
但是exit在终止进程之前,会冲刷缓冲区,将缓冲区的数据输出
printf一定是先把数据写入缓冲区中,合适的时候,再进行刷这个缓冲区,缓冲区绝对不在内核中,在用户区
进程等待
进程等待:通过系统调用wait/waitpid,来进行对子进程进行状态检测与回收的功能
1、子进程退出,父进程如果不读取子进程的退出信息,子进程就会变成僵尸进程,进而造成内存泄漏
2、进程一旦变成僵尸进程,那么就算是kill -9命令也无法将其杀死,因为谁也无法杀死一个已经死去的进程
3、对于一个进程来说,最关心自己的就是其父进程,因为父进程需要知道自己派给子进程的任务完成的如何
4、父进程需要通过进程等待的方式,回收子进程资源,获取子进程的退出信息
父进程通过调用wait/waitpid进行僵尸进程的回收问题
监控脚本
while :;dops ajx |head -1 && ps ajx | grep testWait | grep -v grep ;sleep 1 ;echo"------------"; done
wait是等待任意一个子进程退出
如果是多个子进程僵尸,如何利用wait回收?
1#include<stdio.h>2#include<unistd.h>3#include<stdlib.h>4#include<sys/types.h>5#include<sys/wait.h> 6#define N 10 7 void Runchild ()8{9 int cnt =5;10 while(cnt)11{12 printf("child pid:%d ,ppid%d\n",getpid() ,getppid());13 sleep(1);14 cnt--;15}16}17 int main()18{19 for( int i =0; i < N ;i ++ )20{21 pid_t id= fork();22 if(id==0)23{24 //子进程
25 Runchild ();26 exit(0);27}28 //父进程
29 printf("create child process: %d success\n", id);30}31 sleep(10);32 //等待
33 for( int i =0; i < N ; i++ )34{35 pid_t id= wait(NULL);36 if( id>0)37{38 printf("wait %d success\n", id);39}4041}4243 sleep(5);44return0;45}
如果父进程在等待子进程,如果一个子进程或多个子进程不退出 ,父进程会在调用wait时,父进程就一直拿不到子进程的pid , 父进程会一直等待子进程退出,父进程这种状态叫阻塞等待
#include<stdio.h>
2 #include<unistd.h>
3 #include<stdlib.h>
4 #include<sys/types.h>
5 #include<sys/wait.h>
6 #define N 10
7 void Runchild ()
8 {
9 int cnt =5 ;
10 while(1)
11 {
12 printf("child pid:%d ,ppid%d\n",getpid(),getppid());
13 sleep(1);
14 cnt--;
15 }
16 }
17 int main()
18 {
19 for( int i =0 ; i < N ;i ++)
20 {
21 pid_t id = fork();
22 if( id ==0 )
23 {
24 //子进程
25 Runchild ();
26 exit(0);
27 }
28 //父进程
29 printf("create child process: %d success\n", id);
30 }
31 //sleep(10);
32 //等待
33 for( int i = 0 ; i < N ; i++)
34 {
35 pid_t id = wait(NULL);
36 if( id>0 )
37 {
38 printf("wait %d success\n", id);
39 }
40
41 }
42
43 sleep(5);
44 return 0 ;
45 }
waitpid
等待指定子进程或任意子进程
waitpid的返回值:
1、等待成功返回被等待进程的pid。
2、如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0。
3、如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在。
pid:待等待子进程的pid,若设置为-1,则等待任意子进程
status:输出型参数(通过指针,把函数内部的数据带出来)
获取子进程的退出状态,不关心可设置为NULL
status:操作系统会去找对应id的子进程,并且等待该子进程,如果该子进程退出 ,操作系统会将子进程的退出信息拷贝到status指针所指向的变量当中
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 #define N 107voidRunchild()8{9int cnt =5;10while(1)11{12printf("child pid:%d ,ppid%d\n",getpid(),getppid());13sleep(1);14 cnt--;15}16}17intmain()18{45 pid_t id =fork();46if(id <0)47{48perror("fork");49return1;50}51elseif( id ==0)52{53//child 5455int cnt =5;56while(cnt)57{58printf("I am a child ,pid:%d , ppid:%d cnt: %d\n",getpid(),getppid(),cnt);59 cnt --;60sleep(1);61}62exit(1);63}64else// parent 65{66int cnt =10;67while(cnt )68{69printf("I am a parent ,pid:%d , ppid:%d cnt: %d\n",getpid(),getppid(),cnt);70 cnt --;71sleep(1);72}73// pid_t ret = wait(NULL);7475int status =0;//输出型参数76//操作系统会去找对应id的子进程,并且等待该子进程,如果该子进程退出 ,操作系统会将子进程的退出信息拷贝到status指针所指向的变量当中77 pid_t ret =waitpid( id,&status ,0);7879//等待成功80if( ret ==id )//id是子进程的pid81{82//status存放的是子进程的退出信息83printf("wait success,ret:%d, status: %d\n", ret, status);84}85sleep(5);868788}89return0;90}
为什么status是256 ?
在子进程中 ,exit函数里面,我们设置的是1
退出码设置的是1 ,也就是00000001,00000001就是256
子进程退出,一共会有3种退出场景
1、代码运行完毕,结果正确
2、代码运行完毕,结果不正确
3、代码异常终止
父进程等待,需要获得子进程退出的哪些信息?
1、子进程代码是否异常
2、如果没有异常,通过退出码判断来结果是否正确
不同的退出码表示不同的出错原因
status是一个整型变量,但status不能简单的当作整型来看待,status的不同比特位所代表的信息不同,具体细节如下(只研究status低16比特位)
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 #define N 107voidRunchild()8{9int cnt =5;10while(1)11{12printf("child pid:%d ,ppid%d\n",getpid(),getppid());13sleep(1);14 cnt--;15}16}17intmain()18{45 pid_t id =fork();46if(id <0)47{48perror("fork");49return1;50}51elseif( id ==0)52{53//child 5455int cnt =5;56while(cnt)57{58printf("I am a child ,pid:%d , ppid:%d cnt: %d\n",getpid(),getppid(),cnt);59 cnt --;60sleep(1);61}62exit(1);63}64else// parent 65{66int cnt =10;67while(cnt )68{69printf("I am a parent ,pid:%d , ppid:%d cnt: %d\n",getpid(),getppid(),cnt);70 cnt --;71sleep(1);72}73// pid_t ret = wait(NULL);7475int status =0;//输出型参数76//操作系统会去找对应id的子进程,并且等待该子进程,如果该子进程退出 ,操作系统会将子进程的退出信息拷贝到status指针所指向的变量当中77 pid_t ret =waitpid( id,&status ,0);7879//等待成功80if( ret ==id )//id是子进程的pid81{82//status存放的是子进程的退出信息83//7F 0111 1111 84//0xFF85printf("wait success,ret:%d, exit sig : %d, exit code:%d\n", ret, status&0x7F,(status>>8)&0xFF);//打印的分别是 id, 信号, 退出码86}87sleep(5);888990}91return0;92}
通过收到信号判断是否异常
通过看退出码判断是否结果正确
系统当中提供了两个宏来获取退出码和退出信号
WIFEXITED(status):用于查看进程是否是正常退出,本质是检查是否收到信号
WEXITSTATUS(status):用于获取进程的退出码
exitNormal =WIFEXITED(status);//获取退出信号,判断是否正常退出
exitCode =WEXITSTATUS(status);//获取退出码
例如:
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 #define N 107voidRunchild()8{9int cnt =5;10while(1)11{12printf("child pid:%d ,ppid%d\n",getpid(),getppid());13sleep(1);14 cnt--;15}16}17intmain()18{45 pid_t id =fork();46if(id <0)47{48perror("fork");49return1;50}51elseif( id ==0)52{53//child 5455int cnt =5;56while(cnt)57{58printf("I am a child ,pid:%d , ppid:%d cnt: %d\n",getpid(),getppid(),cnt);59 cnt --;60sleep(1);61}62exit(1);63}64else// parent 65{66int cnt =10;67while(cnt )68{69printf("I am a parent ,pid:%d , ppid:%d cnt: %d\n",getpid(),getppid(),cnt);70 cnt --;71sleep(1);72}73// pid_t ret = wait(NULL);7475int status =0;//输出型参数76//操作系统会去找对应id的子进程,并且等待该子进程,如果该子进程退出 ,操作系统会将子进程的退出信息拷贝到status指针所指向的变量当中77 pid_t ret =waitpid( id,&status ,0);7879//等待成功80if( ret ==id )//id是子进程的pid81{82//status存放的是子进程的退出信息83//7F 0111 1111 84//0xFF85//printf("wait success,ret:%d, exit sig : %d, exit code:%d\n", ret, status&0x7F , (status>>8) &0xFF ); //打印的分别是 id, 信号, 退出码if(WIFEXITED(status))88{89printf("进程是正常跑完的,退出码:%d\n",WIFEXITED(status));90}91else92{93printf("进程出异常了\n");94}86}87sleep(5);888990}91return0;92}
以下代码中同时创建了10个子进程
父进程再使用waitpid函数指定等待这10个子进程
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 #define N 107voidRunchild()8{9int cnt =5;10while(cnt)11{12printf("child pid:%d ,ppid%d\n",getpid(),getppid());13sleep(1);14 cnt--;15}16}17intmain()18{//创建多进程19for(int i =0; i < N ;i ++)20{21 pid_t id =fork();22if( id ==0)23{24//子进程25Runchild();26exit(i);27}28//父进程 29printf("create child process: %d success\n", id);30}31// sleep(10);32//多进程等待33for(int i =0; i < N ; i++)34{35// pid_t id = wait(NULL);36int status =0;37 pid_t id=waitpid(-1,&status ,0);3839if( id>0)40{41printf("wait %d success,exit code:%d\n", id,WEXITSTATUS(status ));//id ,退出码42}4344}4546sleep(5);108return0;109}
options:
1、options为0时,父进程阻塞等待
2、options为WNOHANG时,若等待的子进程没有结束,则waitpid函数直接返回0,不予以等待。若正常结束,则返回该子进程的pid
非阻塞轮询
options为WNOHANG时,父进程等待子进程中实现非阻塞
例如,父进程可以隔一段时间调用一次waitpid函数,若是等待的子进程尚未退出,则父进程可以先去做一些其他事,过一段时间再调用waitpid函数读取子进程的退出信息。
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 #define N 107voidRunchild()8{9int cnt =5;10while(cnt)11{12printf("child pid:%d ,ppid%d\n",getpid(),getppid());13sleep(1);14 cnt--;15}16}17intmain()18{48 pid_t id =fork();49if(id <0)50{51perror("fork");52return1;53}54elseif( id ==0)55{56//child 5758int cnt =3;59while(cnt)60{61printf("I am a child ,pid:%d , ppid:%d cnt: %d\n",getpid(),getppid(),cnt);62 cnt --;63sleep(1);64}65exit(11);66}67else// parent 68{78int status =0;//输出型参数79//操作系统会去找对应id的子进程,并且等待该子进程,如果该子进程退出 ,操作系统会将子进程的退出信息拷贝到status指针所指向的变量当中80while(1)//轮询81{8283 pid_t ret =waitpid( id,&status , WNOHANG );//非阻塞等待8485//等待成功86if( ret >0)//id是子进程的pid87{88//status存放的是子进程的退出信息89//7F 0111 1111 90//0xFF91// printf("wait success,ret:%d, exit sig : %d, exit code:%d\n", ret, status&0x7F , (status>>8) &0xFF ); //打印的分别是 id, 信号, 退出码9293if(WEXITSTATUS(status))94{95printf("进程是正常跑完的,退出码:%d\n",WEXITSTATUS(status));96}97else98{99printf("进程出异常了\n");100}101break;102}103elseif( ret<0)104{105printf("wait failed\n");106break;107}108else//ret==0109{110printf("子进程还没有退出我再等等\n");111sleep(1);112}113}114sleep(3);115116117}118return0;119}
WNOHANG:
非阻塞等待:
1、如果子进程已经退出,waitpid成功返回
2、如果子进程没有退出,并且等待期间没有异常,waitpid检测完子进程,发现子进程没有退出,waitpid立马返回0
非阻塞轮询 +父进程做自己的事情
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 #define N 107 #define TASK_NUM 1018typedefvoid(*task_t )();//函数指针1920 task_t tasks[TASK_NUM];21222324intAddTask(task_t t );29voidtask1()30{31printf("这是一个执行打印日志的任务\n");32}33voidtask2()34{35printf("这是一个执行检测网络健康状态的任务\n");36}37voidtask3()38{39printf("这是一个进行绘制图形界面的任务\n");40}41voidInitTask()42{43int i =0;44for(; i< TASK_NUM ; i++)45{46 tasks[i]=NULL;47}48AddTask(task1);49AddTask(task2 );50AddTask(task3);51}5253intAddTask( task_t t )54{55//找到数组中为空的位置56int i =0;57for(; i< TASK_NUM ; i++)58{59if( tasks[i]==NULL)60{61break;62}63}64if( i == TASK_NUM )65{66return-1;67}68 tasks[i]=t ;//放任务6970return0;72}76voidExecuteTask()77{78int i =0;79for(; i<TASK_NUM ; i++)80{81//如果为空 ,继续走82if( tasks[i]==NULL)83{84continue;85}86//不为空87 tasks[i]();88}89}92intmain()93{123 pid_t id =fork();124if(id <0)125{126perror("fork");127return1;128}129elseif( id ==0)130{131//child 133int cnt =5;134while(cnt)135{136printf("I am a child ,pid:%d , ppid:%d cnt: %d\n",getpid(),getppid(),cnt);137 cnt --;138sleep(1);139}140exit(11);141}142else// parent 143{153int status =0;//输出型参数154//操作系统会去找对应id的子进程,并且等待该子进程,如果该子进程退出 ,操作系统会将子进程的退出信息拷贝到status指针所指向的变量当中155InitTask();156while(1)//轮询157{159 pid_t ret =waitpid( id,&status , WNOHANG );//非阻塞等待161//等待成功162if( ret >0)//id是子进程的pid163{164//status存放的是子进程的退出信息165//7F 0111 1111 166//0xFF167// printf("wait success,ret:%d, exit sig : %d, exit code:%d\n", ret, status&0x7F , (status>>8) &0xFF ); //打印的分别是 id, 信> 号, 退出码168169if(WEXITSTATUS(status))170{171printf("进程是正常跑完的,退出码:%d\n",WEXITSTATUS(status));172}173else174{175printf("进程出异常了\n");176}177break;178}179elseif( ret<0)180{181printf("wait failed\n");182break;183}184else//ret==0185{189ExecuteTask();190usleep(500000);191}192}193sleep(3);196}197return0;198}
父进程并不需要立马回收子进程,可以延迟一点时间回收子进程
如果有很多子进程,这些进程的退出时间比较集中,此时父进程统一进行回收反而更好
父进程将所有的子进程创建出来,由父进程对创建的子进程进行退出 ,正常情况下,父进程是最后一个退出的进程
替换原理
execl
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4intmain()5{6printf(" before : I am a process , pid %d , ppid %d\n",getpid(),getppid());78//最后一个参数必须是NULL 9execl("/usr/bin/ls","ls","-a","-l",NULL);1011printf(" after : I am a process , pid %d , ppid %d\n",getpid(),getppid());12return0;13}
程序替换:
用ls的代码替换自己的代码,用ls的数据替换自己的数据
一旦替换完成之后,只需要将页表的物理地址修改
然后,从0开始执行
进行进程程序替换时,有没有创建新的进程?
不创建新进程,只进行进程的程序代码和数据的替换工作
我自己程序在运行的时候,当运行到程序替换的位置时,可执行程序用execl加载时,execl用新程序的代码替换老程序的代码,用新程序的数据替换老程序的数据,让CPU执行新程序的入口地址,整个过程中,只把当前进程的代码和数据进行替换,并没有更改当前进程,没有创建新进程
再看下面的代码
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6intmain()7{8 pid_t id =fork();9if(id ==0)10{11//child 1213printf(" before : I am a process , pid %d , ppid %d\n",getpid(),getppid());14sleep(5);15//最后一个参数必须是NULL16execl("/usr/bin/ls","ls","-a","-l",NULL);17printf(" after : I am a process , pid %d , ppid %d\n",getpid(),getppid());18exit(0);19}20//father 21 pid_t ret =waitpid(id ,NULL,0);22if(ret >0)23{24printf("wait success, father pid :%d , ret id:%d\n",getpid(), ret);25}26sleep(5);27return0;28}
子进程在没有执行execl,子进程的代码和数据是父进程的代码和数据
当子进程在在执行execl,把ls的代码替换进来时,替换数据时发生写时拷贝
程序替换成功之后,exec类型的函数后续的代码不会被执行,
如果替换失败 ,才可能执行后续代码
exec类型的函数,只有失败有返回值,函数执行成功,无返回值
程序加载到内存中 ,CPU如何得知程序的入口地址?
Linux中形成的可执行程序,是ELF格式,可执行程序在最开始有表头,可执行程序的入口地址就在表中,程序加载到内存中,可以不将代码和数据加载到内存,但是一定要将表头加载到内存中
execl
替换函数有六种以exec开头的函数,它们统称为exec函数
第一个参数是要执行程序的路径(绝对路径或者相对路径),第二个参数是可变参数列表,表示你要如何执行这个程序,并以NULL结尾
//最后一个参数必须是NULLexecl("/usr/bin/ls","ls","-a","-l",NULL);
execlp
execlp中的p , p是PATH,表示 execlp函数自己会在默认的PATH环境变量中查找
第一个参数不用带可执行程序的路径(绝对路径或者相对路径),execlp自己会去PATH环境变量中去找可执行程序所对应的路径
第一个参数是要执行程序的名字,第二个参数是可变参数列表,表示你要如何执行这个程序,并以NULL结尾
execlp("ls","ls","-a","-l",NULL);
execv
execv中的 v ,可以理解为vector
第一个参数是要执行程序的路径(绝对路径或者相对路径),第二个参数是一个指针数组,数组当中的内容表示你要如何执行这个程序,数组以NULL结尾
char*const myargv[]={"ls","-l","-a",NULL};execv("/usr/bin/ls", myargv );
在命令行中,所有的进程都是Bash的子进程,所有的进程在启动时都是采用exec系列函数来启动执行的 ,exec系列函数承担着加载器的效果,把可执行程序导到内存中
execvp
execvp中的p , p是PATH,表示 execvp函数自己会在默认的PATH环境变量中查找
execvp中的 v ,可以理解为vector
第一个参数不用带可执行程序的路径(绝对路径或者相对路径),execvp自己会去PATH环境变量中去找可执行程序所对应的路径
第一个参数是要执行程序的名字,第二个参数是一个指针数组,数组当中的内容表示你要如何执行这个程序,数组以NULL结尾
char*const myargv[]={"ls","-l","-a",NULL};execvp("ls", myargv );
execle
execle 中的e 是env环境变量
Makefile形成两个可执行程序
1.PHONY:all
2 all:otherExe mycommand
34 otherExe:otherExe.cpp
5 g++-o $@ $^-std=c++116 mycommand :mycommand.c
7 gcc -o $@ $^-std=c99
8.PHONY:clean
9 clean:10 rm -rf mycommand otherExe
用c语言去调用c++形成的可执行程序
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6intmain()7{8 pid_t id =fork();9if(id ==0)10{11//child 13printf(" before : I am a process , pid %d , ppid %d\n",getpid(),getppid());22execl("./otherExe","otherExe",NULL);23printf(" after : I am a process , pid %d , ppid %d\n",getpid(),getppid());24exit(1);25}26//father 27 pid_t ret =waitpid(id ,NULL,0);28if(ret >0)29{30printf("wait success, father pid :%d , ret id:%d\n",getpid(), ret);31}32sleep(5);33return0;34}
无论是我们的可执行程序,还是脚本,为什么能跨语言调用?
所有语言运行起来,本质都是进程
在mycommand.c中execv函数 ,我们没有传环境变量的参数 ,为什么能打印出环境变量
环境变量是什么时候给进程的?
环境变量也是数据,创建子进程的时候,环境变量就已经被子进程继承下去了
在程序替换中,环境变量信息,不会被替换
如果想给子进程传递环境变量,该怎么传递?
1、新增环境变量:父进程的地址空间中直接putenv
putenv("PRIVALUE_ENV=66666");
execle
第一个参数是要执行程序的路径(绝对路径或者相对路径),第二个参数是可变参数列表,表示你要如何执行这个程序,并以NULL结尾,第三个参数是你自己设置的环境变量。
例如,你设置了PRIVALUE_ENV环境变量,在mycommand程序内部就可以使用该环境变量。
externchar** environ;execle("./otherExe ","otherExe","-a","-w","-v",NULL,environ );
覆盖之前的环境变量
char*const myenv[]={"MYVAL=1111","MYPATH=/usr/bin/xxx",NULL};execle("./otherExe","otherExe","-a","-w","-v",NULL,myenv );
如果你觉得这篇文章对你有帮助,不妨动动手指给点赞收藏加转发,给鄃鳕一个大大的关注你们的每一次支持都将转化为我前进的动力!!!
版权归原作者 鄃鳕 所有, 如有侵权,请联系我们删除。