Linux进程实例
fork() 函数的使⽤
fork调⽤的⼀个奇妙之处就是它仅仅被调⽤⼀次,却能够返回两次,它可能有三种不同的返回值:
1)在⽗进程中,fork返回新创建⼦进程的进程ID;
2)在⼦进程中,fork返回0;
3)如果出现错误,fork返回⼀个负值;
在fork函数执⾏完毕后,如果创建新进程成功,则出现两个进程,⼀个是⼦进程,⼀个是⽗进程。在⼦进程中,fork函数返回0,在⽗进程中,fork返回新创建⼦进程的进程ID。我们可以通过fork返回的值来判断当前进程是⼦进程还是⽗进程。
#include<stdio.h>
#include<unistd.h>
int main(){
printf("before pid=%d\n",getpid());
pid_t pid =fork();
int a =100;linux系统登录
if(pid <0){
return-1;
}else if(pid ==0){
a =20;
printf("this is child! pid=%d a=%d\n",getpid(), a);
}else{
sleep(1);
printf("this is father a=%d pid=%d\n", a,getpid());
}
return0;
}
僵⼫进程
产⽣原因: ⼦进程先于⽗进程退出, 部分资源没回收。当进程退出并且⽗进程没有读取到⼦进程退出的返回代码是就会产⽣僵⼫进程,僵⼫进程会以终⽌状态保存在进程表中,并且会⼀直等待⽗进程读取退出状态代码
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(){
pid_t pid;
pid =fork();
if(pid <0){
return-1;
}
else if(pid ==0){
printf("i am child! pid=%d\n",getpid());
sleep(3);
exit(1);
}else{
printf("i am parent! pid=%d\n",getpid());
while(1){
sleep(1);
printf("i don't care my child\n");
}
}
}
可以看到 zombie⼦进程在三秒后变为僵⼫状态
危害
维护退出状态本⾝就要⽤数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态⼀直不退出,PCB ⼀直都要维护。
如果⼀个⽗进程创建了很多⼦进程,都不会回收,就会造成内存资源浪费。因为数据结构对象本⾝就要占内存。
在每个进程退出的时候,内核释放该进程所有的资源,包括打开的⽂件,占⽤的内存等。 但是仍然为其保留⼀定的信息(包括进程号the process ID,退出状态the termination status of the process,运⾏时间the amount of CPU time taken by the process等)。
直到⽗进程通过wait / waitpid来取时才释放。 但这样就导致了问题,如果进程不调⽤wait / waitpid的话,那么保留的那段信息就不会释放,其进程号就会⼀直被占⽤,但是系统所能使⽤的进程号是有限的,如果⼤量的产⽣僵死进程,将因为没有可⽤的进程号⽽导致系统不能产⽣新的进程. 此即为僵⼫进程的危害,应当避免。
孤⼉进程
孤⼉进程
产⽣原因: ⽗进程先于⼦进程退出
⼀个⽗进程退出,⽽它的⼀个或多个⼦进程还在运⾏,那么那些⼦进程将成为孤⼉进程。孤⼉进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集⼯作
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(){
pid_t pid;
pid =fork();
if(pid <0){
return-1;
}else if(pid ==0){
printf("i am parent pid=%d\n",getpid());
sleep(10);
}else{
printf("i am child pid=%d\n",getpid());
sleep(3);
exit(1);
}
return0;
}
环境变量
概念
指在操作系统中⽤来指定操作系统运⾏环境的⼀些参数。环境变量通常具有特殊⽤途,在系统中具有全局特性。
环境变量通常具有全局属性,可以被⼦进程继承下去。
常见的环境变量
(1)PATH:指定命令的搜索路径
(2)HOME:指定⽤户的主⼯作⽬录(即⽤户登录到Linux系统中时,默认的⽬录)
(3)HISTSIZE:指保存历史命令记录的条数
(4)SHELL:当前Shell,它的值通常是/bin/bash
查看环境变量的⽅法
echo $NAME //NAME:环境变量名称
和环境变量相关的命令
(1)echo:显⽰某个环境变量值
(1)echo:显⽰某个环境变量值
(2)export:设置⼀个新的环境变量
(3)env:显⽰所有环境变量
(4)unset:清楚环境变量
(5)set:显⽰本地定义的shell变量和环境变量
setenv
作为setenv函数
作⽤:增加或者修改环境变量。
注意:通过此函数并不能添加或修改 shell 进程的环境变量,或者说通过setenv函数设置的环境变量只在本进程,⽽且是本次执⾏中有效。如果在某⼀次运⾏程序时执⾏了setenv函数,进程终⽌后再次运⾏该程序,上次的设置是⽆效的,上次设置的环境变量是不能读到的。
头⽂件:#include<stdlib.h>
注:stdlib.h在Linux和Windows中略不同,⽐如setenv函数是⽤在linux中的,在Windows中没有setenv函数⽽⽤putenv来代替
函数声明:int setenv(const char *name,const char * value,int overwrite);
函数说明:setenv()⽤来改变或增加环境变量的内容。参数name为环境变量名称字符串。参数 value则为变量内容,参数overwrite⽤来决定是否要改变已存在的环境变量。如果没有此环境变量则⽆论overwrite为何值均添加此环境变量。若环境变量存在,当overwrite不为0时,原内容会被改为参数value所指的变量内容;当overwrite为0时,则参数value会被忽略。返回值 执⾏成功则返回0,有错误发⽣时返回-1。
相关函数:getenv,putenv,unsetenv
作为Linux中setenv命令
Linux中的功能:查询或显⽰环境变量
语法:setenv [变量名称] [变量值]
setenv⽤于在C shell设置环境变量的值
⽤法:setenv ENVVAR value
ENVVAR 为所要设置的环境变量的名。value为所要设置的环境变量的值
例:setenv PATH "/bin:/usr/bin:usr/sbin:"设置环境path的搜索路径为/bin,/usr/bin以及/usr/sbin
export
Linux中的功能:设置或显⽰环境变量(⽐如我们要⽤⼀个命令,但这个命令的执⾏⽂件不在当前⽬录,这样我们每次⽤的时候必须制定执⾏⽂件的⽬录,⿇烦,在代码中先执⾏export,这个相当于告诉程序,执⾏某某东西时,需要的⽂件或什么东西在这些⽬录⾥)
说明:在shell中执⾏程序时,shell会提供⼀组环境变量。export可新增,修改或删除环境变量,供后续执⾏的程序使⽤。export 的效⼒仅及于该次登陆操作。
语法:export [-fnp] [变量名称] = [变量设置值]
参数说明:
-f 代表[变量名称]中为函数名称。
-n 删除指定的变量。变量实际上并未删除,只是不会输出到后续指令的执⾏环境中。
-p 列出所有的shell赋予程序的环境变量。
延伸:export设置环境变量是暂时的,只在本次登录中有效,可修改如下⽂件来使命令长久有效。
注意:
1、执⾏脚本时是在⼀个⼦shell环境运⾏的,脚本执⾏完后该⼦shell⾃动退出;
2、⼀个shell中的系统环境变量才会被复制到⼦shell中(⽤export定义的变量);
3、⼀个shell中的系统环境变量只对该shell或者它的⼦shell有效,该shell结束时变量消失(并不能返回到⽗shell中)。
4、不⽤export定义的变量只对该shell有效,对⼦shell也是⽆效的。
⼀个变量创建时,它不会⾃动的为在它之后创建的shell进程所知。⽽命令export可以向后⾯的shell传递变量的值。当⼀个shell脚本调⽤并执⾏时,它不会⾃动得到原来脚本(调⽤者)⾥定义的变量的访问权,除⾮这些变量已经被显⽰地设置为可⽤。export命令可以⽤于传递⼀个或多个变量的值到任何后续脚本。
export设置环境变量是暂时的,只在本次登录中有效,若想要使得开机时⾃动加载这个环境变量免除以后每次设置,可将其写
⼊/etc/re.local
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论