Linux进程入门学习(四)-进程启动退出
来源:互联网 发布:b超数据算胎儿体重公式 编辑:程序博客网 时间:2024/05/18 01:53
1. 进程的退出
exit 函数用于进程退出
头文件:#include <stdlib.h>
函数原型:void exit(int status);
参数:int status:退出状态值(可以任意写,值规定0 以上的正整数)
返回值:无
_exit 函数用于进程退出
头文件:#include <unistd.h>
函数原型:void _exit(int status);
说明:
1. 如果进程正常退出,则status 一般为0;
2. 如果进程异常退出,则status 一般为非0;
3. 标准C库已经定义两个宏提供使用EXIT_SUCCESS 和 EXIT_FAILURE,正常退出exit(EXIT_SUCCESS ),以及异常退出exit(EXIT_FAILURE)。
exit 与_exit 区别
两者的区别主要是体现在处理过程中,如下图所示:
_exit()函数会直接调用exit 系统调用退出,其间只是清除其使用的内存空间,并销毁其在内核中的各种数据结构。
exit()函数退出时会先自刷新标准IO 总线上残留数据到内核,如果进程注册了“退出处理函”还自动执行这些函数,最后才调用exit 系统调用。
下面用个实例来说明:
代码一:
1 /***************************************************************************** 2 * File Name: exit.c 3 * Author: 谢保成 4 * E-mail: 2446603068@qq.com 5 * Create Time: Fri 18 Aug 2017 07:37:27 PM PDT 6 ******************************************************************************/ 7 8 #include <stdlib.h> 9 #include <stdio.h> 10 #include <unistd.h> 11 12 int main() 13 { 14 printf("Using exit..\n"); 15 printf("This is the end."); 16 exit(0); 17 } 18
运行结果:
代码二:
1 /***************************************************************************** 2 * File Name: exit.c 3 * Author: 谢保成 4 * E-mail: 2446603068@qq.com 5 * Create Time: Fri 18 Aug 2017 07:37:27 PM PDT 6 ******************************************************************************/ 7 8 #include <stdlib.h> 9 #include <stdio.h> 10 #include <unistd.h> 11 12 int main() 13 { 14 printf("Using exit..\n"); 15 printf("This is the end."); 16 _exit(0); 17 } 18
运行结果:
说明:换行符’\n’又刷新缓冲区的作用,所以在第二段代码中,printf(“This is the end.”);没使用’\n’,而且调用_exit结束进程,所以没有打印第二句话。
2. 进程的启动
system 函数用于启动并执行shell 命令
头文件:#include <stdlib.h>
函数原型:int system(const char *command);
返回值:
成功:非0失败:0
参数列表: const char *command:执行的命令
示例: 1 /******************************************************************************* 2 * File Name: system.c 3 * Author: 谢保成 4 * E-mail: 2446603068@qq.com 5 * Create Time: Fri 18 Aug 2017 07:59:07 PM PDT 6 ********************************************************************************/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <unistd.h> 11 12 int main() 13 { 14 system("ls -l"); 15 exit(0); 16 }
运行结果:
Exec 函数族
exec 函数族提供了一种在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段。在执行完之后,原调用进程的内容除了进程号外,其他全部都被替换了。
以下是exec函数族的标准接口
示例1:execl
下面展示子进程被创建出来之后执行的代码,以及如何加载这个指定程序。被子进程加载的示例代码:
1 /******************************************************************************* 2 * File Name: child_elf.c 3 * Author: 谢保成 4 * E-mail: 2446603068@qq.com 5 * Create Time: Fri 18 Aug 2017 10:18:22 PM PDT 6 ********************************************************************************/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <unistd.h> 11 12 int main(int argc, char **argv) 13 { 14 printf("[pid:%d]:child_elf\n", (int)getpid()); 15 exit(EXIT_SUCCESS); 16 } 17
下面是使用exec 函数簇中的execl 来让子进程加载上述代码的示例:
1 /***************************************************************************** 2 * File Name: exec.c 3 * Author: 谢保成 4 * E-mail: 2446603068@qq.com 5 * Create Time: Fri 18 Aug 2017 10:22:45 PM PDT 6 ******************************************************************************/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <unistd.h> 11 12 int main(int argc, char **argv) 13 { 14 pid_t pid; 15 pid = fork(); 16 17 /*父进程*/ 18 if(pid > 0) 19 { 20 printf("[pid :%d] parent.\n", (int)getpid()); 21 exit(EXIT_SUCCESS); 22 } 23 /*子进程*/ 24 if(pid == 0) 25 { 26 printf("[pid:%d]child.\n", (int)getpid()); 27 execl("./child_elf", "./child_elf", NULL); 28 29 /*因为执行execl后,.text代码段中的程序代码已被child_elf替代*/ 30 printf("NEVER be printed\n");/*不执行*/ 31 exit(EXIT_SUCCESS); 32 } 33 34 return 0; 35 } 36
运行结果:
示例2:execv
用一下两行代码代替execl(“./child_elf”, “./child_elf”, NULL);
char *argv[] = {"./child_elf",NULL);execv("./child_elf",argv);
示例3:execlp
执行linux 命令ls -l
execlp("ls", "ls", "-l", NULL);
示例4:execve
1 /******************************************************************************* 2 * File Name: execlp.c 3 * Author: 谢保成 4 * E-mail: 2446603068@qq.com 5 * Create Time: Fri 18 Aug 2017 10:59:34 PM PDT 6 ********************************************************************************/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <unistd.h> 11 12 int main() 13 { 14 char *argv[] = {"ls", "-l", NULL}; 15 char *envp[] = {"PATH=/bin", 0}; 16 execve("/bin/ls", argv, envp); 17 18 return 0; 19 } 20
运行结果:
示例5:execvp
char * argv[] ={ "ls", "-al", 0};execvp("ls", argv);
注意:
在使用exec 函数族时,一定要加上错误判断语句常见的错误原因有:
1)找不到文件或路径,此时errno 被设置为ENOEN
2)数组argv 和envp 忘记用NULL 结束,此时errno 被设置为EFAULT
3)没有对应可执行文件的运行权限,此时errno 被设置为EACCESS
- Linux进程入门学习(四)-进程启动退出
- Linux进程学习(四)之进程的退出
- linux进程(四)之 退出
- linux进程--进程环境(程序的启动与退出)
- Linux进程学习四
- Linux进程学习四
- linux系统编程之进程(四):进程退出exit,_exit区别即atexit函数
- linux系统编程之进程(四):进程退出exit,_exit区别即atexit函数
- linux系统编程之进程(四):进程退出exit,_exit区别即atexit函数
- Linux 学习笔记(四)进程控制
- Linux 进程学习(四)------ sigaction 函数
- Linux 进程学习(四)------ sigaction 函数
- Linux进程-进程的退出
- Linux进程入门学习(一)-认识进程
- Linux进程入门学习(三)-进程创建等待
- Linux进程入门学习(二)-基础知识
- Linux内核-进程退出
- Linux内核-进程退出
- SSH ajax登录
- C++ const 与 nonconst 的简单关系
- composer安装laravel框架
- python scrapy 的概念、安装、使用和案例
- 斐讯固件收集
- Linux进程入门学习(四)-进程启动退出
- Python基础06 循环
- UPC 2017 Summer Training 6 A,D,I
- 1014.Uniform Generator
- 某大学归来后的几点思考
- Android--Handler引起的内存泄露
- 51Nod-1018-排序
- Mybatis实现数据的增删改查(CRUD)
- TabLayout属性详解以及使用用法