Linux下fork()&vfork()的区别、getenv()&setenv()函数以及僵尸进程、孤儿进程讲解
2018-03-14 12:26
896 查看
在讲解僵尸进程前,我们先来说说其它知识,因为我们一会的代码需要用一个叫fork()的系统调用来创建子进程,所以我们先来聊聊fork()这个系统调用。
运行程序,利用ps aux | grep zombieprocess指令查看进程状态,结果如下:
程序运行结果:
子进程结束前:
子进程结束后:
注意查看第八列的状态。
结果:
1号进程为init进程。
后面再介绍关于环境变量的两个函数getenv()、setenv():
此函数获得相应环境变量的值,参数为环境变量的字符串,成功返回对应变量的值字符串,失败返回空指针。
输出结果:
此函数用于创建环境变量或改变环境变量的值,name为所要改变或创建环境变量的值,value为环境变量的值,overwrite为标志位,当环境变量不存在时,无论overwrite为何值创建环境变量并以value赋值,当环境变量存在时,若overwrite非0时改变环境变量的值,当overwrite为0时忽略value的值,函数调用成功返回0,失败返回-1。
输出结果:
fork()、vfork()的区别:
#include<unistd.h> pid_t fork(void); //pid_t为int的类型别名 //fork()是一个比较特殊的函数,调用成功返回两个值,调用失败返回-1. //那么到底fork()调用成功是如何返回两个值的呢?原来,fork()是用来 //创建子进程的,一但fork()调用成功,便会以父进程为模板创建子进程( //代码段共享、数据段(写时拷贝)的拷贝),父、子进程都从fork()的下一句指令 //开始执行,但父、子进程的执行顺序无法确定,依赖于调度器的调度,父进程 //返回子进程的pid,子进程返回0,对于调用失败的情况可能有以下的两种情况, //1)内存不足,内核没有足够的空间创建管理进程的数据结构(task_struct) //2)进程数已经达到系统规定的上限 //与vfork()相关的还有一个叫做vfork()的函数,请看下面讲解: #include<unistd.h> #include<sys/types.h> pid_t vfork(void); //vfork()的行为基本类似fork(),但两者有以下区别: //1)fork()之后,子进程和父进程共享代码段、数据段写时拷贝, //vfork()之后,代码段、数据段均共享。 //2)fork()、之后父、子进程的调度顺序依赖于调度器,vfork()之后, //子进程先执行,在子进程调用exec()或_exit()之后父进程才可运行, //不调用exec()或_exit(),则出现段错误,在调用exec()或_exit()之前, //依赖父进程的动作,则会出现死锁。
僵尸进程:
所谓僵尸进程,是指那些父进程还在运行,子进程已经退出,但是父进程并没有查看子进程的退出状态,子进程一直以终止状态(Z状态)保存在进程表中等待父进程查看退出状态,此时,子进程便为僵尸进程。#include<stdio.h> #include<unistd.h> #include<sys/types.h> int main(){ pid_t ret = fork(); if(ret < 0){ //fork失败,打印错误信息 perror("fork "); return 1; }else if(ret > 0){ //father进程 printf("father: pid_t = %d begin\n",getpid());//打印父进程pid sleep(30);//延时30s printf("father is end!\n"); }else{ //child进程 printf c141 ("child: pid_t = %d is begin...\n",getpid());//打印子进程pid sleep(5); printf("child: is end\n"); } return 0; }
运行程序,利用ps aux | grep zombieprocess指令查看进程状态,结果如下:
程序运行结果:
子进程结束前:
子进程结束后:
注意查看第八列的状态。
孤儿进程:
孤儿进程是指:父进程运行提前结束,子进程还在运行时,子进程便叫做孤儿进程。#include<unistd.h> #include<sys/types.h> #include<stdio.h> #include<stdlib.h> int main(){ pid_t ret = fork(); if(ret < 0){ perror("fork:"); return 1; }else if(ret == 0){ //child printf("child pid:%d is begin!\n",getpid()); sleep(20); printf("child father id:%d \n",getppid()); printf("child is end! \n"); }else{ //father printf("father pid:%d is begin!\n",getpid()); sleep(5); printf("father is end!\n"); } return 0; }
结果:
1号进程为init进程。
环境变量:
下面简单的介绍关于环境变量的指令与函数。echo $env_name:此命令查看相应环境变量的值。env_name为环境变量的名字。
export env_name="env_value":此命令创建一个新的环境变量。env_name为环境变量名,env_value为环境变量的值。
env:查看所有环境变量。
后面再介绍关于环境变量的两个函数getenv()、setenv():
char *getenv(const char *name);
此函数获得相应环境变量的值,参数为环境变量的字符串,成功返回对应变量的值字符串,失败返回空指针。
#include<stdio.h> #include<stdlib.h> int main(){ //char *getenv(const char *name); char *env = getenv("PATH"); if(env){ printf("%s\n",env); } return 0; }
输出结果:
[DELL@MiWiFi-R1CL-srv class_code]$ ./environ /usr/java/jdk/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/DELL/.local/bin:/home/DELL/bin:./ [DELL@MiWiFi-R1CL-srv class_code]$
int setenv(const char *name, const char *value, int overwrite);
此函数用于创建环境变量或改变环境变量的值,name为所要改变或创建环境变量的值,value为环境变量的值,overwrite为标志位,当环境变量不存在时,无论overwrite为何值创建环境变量并以value赋值,当环境变量存在时,若overwrite非0时改变环境变量的值,当overwrite为0时忽略value的值,函数调用成功返回0,失败返回-1。
#include<stdio.h> #include<stdlib.h> int main(){ //int setenv(const char *name, const char *value, int overwrite); int ret = setenv("MYENV","hello world",1); if(ret == 0){ printf("MYENV:"); char *env = getenv("MYENV"); if(env){ printf("%s\n",env); }else{ perror("getenv:"); } }else{ perror("setenv:"); } return 0; }
输出结果:
[DELL@MiWiFi-R1CL-srv class_code]$ ./environ MYENV:hello world [DELL@MiWiFi-R1CL-srv class_code]$
相关文章推荐
- linux进程创建过程与原理 & linux进程创建:fork、vfork和clone联系与区别
- linux进程知识 程序存储、crontab、fork与vfork、exec、_exit()、wait()与waitpid()、孤儿和僵尸
- linux进程知识 程序存储、crontab、fork与vfork、exec、_exit()、wait()与waitpid()、孤儿和僵尸
- .linux进程知识 程序存储、crontab、fork与vfork、exec、_exit()、wait()与waitpid()、孤儿和僵尸 文件读写 文件锁、select、poll
- linux中fork()和vfork()函数的使用和区别
- linux系统编程之进程(三):进程复制fork,孤儿进程,僵尸进程
- linux 中的进程wait()和waitpid函数,僵尸进程详解,以及利用这两个函数解决进程同步问题
- linux进程创建过程与原理 fork,vfork,clone的区别
- 进程创建函数fork和vfork的区别
- 进程创建函数fork和vfork的区别
- 使用C语言的fork()函数在Linux中创建进程的实例讲解
- 僵尸进程 & 孤儿进程 & UNIX异常控制流相关函数
- Linux系统开发 4 进程资源 环境 fork()子进程 wait() waitpid()僵尸 孤儿进程
- Linux产生僵尸进程和孤儿进程及区别
- Linux进程函数fork(),vfork(),execX()的深入理解
- Linux进程理解与实践(二)僵尸&孤儿进程 和文件共享
- linux系统编程之进程(三):进程复制fork,孤儿进程,僵尸进程
- linux进程创建:fork、vfork和clone联系与区别
- linux进程创建:fork、vfork和clone联系与区别
- linux系统编程之进程(四):wait/waitpid函数与僵尸进程、fork 2 times