【linux】进程创建、等待、终止
来源:互联网 发布:win10双硬盘安装ubuntu 编辑:程序博客网 时间:2024/06/05 08:40
创建进程—fork函数
函数原型:pid_t fork(void);
返回值:子进程返回0;父进程返回子进程pid,失败返回-1(失败的原因:1内存不够;2系统进程数量太多);
注意:fork之前,父进程独立执行,fork之后,父子两个执行流分别执行。但是父子进程谁先执行是由系统调度决定。
写实拷贝:父进程创建子进程后,子进程室父进程的副本;父子代码共享,父子不写入时,数据也是共享。当任意一方试图写入时,便以写实拷贝的方式各自创建一份副本。
代码:
1 #include<stdio.h> 2 #include<unistd.h> 3 4 int main() 5 { 6 pid_t pid = fork(); 7 if(pid>0){ 8 sleep(3); 9 printf("I am father:%d\n",getpid()); 10 }else if(pid==0){ 11 printf("I am child:%d\n",getpid()); 12 sleep(1); 13 }else{ 14 perror("fork"); 15 } 16 return 0; 17 }
vfork函数:也是创建进程,用法跟fork相似;
不同的是:
1、vfork一个子进程,父子进程共享地址空间,而fork的子进程具有独立的地址空间。
2、vfork保证子进程先运行,直到调用exec或者exit之后父进程才运行。
代码:
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<stdlib.h> 4 int flag = 100;//设定一个全局变量100 5 int main() 6 { 7 pid_t pid = fork(); 8 if(pid>0){ 9 sleep(2); 10 flag = 10;//父进程把flag变为10; 11 printf("father:%d;flag = %d\n",getpid(),flag); 12 exit(0); 13 }else if(pid==0){ 14 flag = 0; //子进程把flag变为0; printf("child:%d,father_id=%d,flag=%d\n",getpid(),getppid(),flag); 16 sleep(5); 17 }else{ 18 perror("fork"); 19 } 20 return 0; 21 }
结果:
我们看到子进程改变了父进程的的值,因为子进程实在父进程的地址空间运行。)
进程等待—wait和waitpid
进程等待必要性:
1、子进程退出,如果父进程不管不顾,就可能造成僵尸进程的问题,造成内存泄露。
2、父进程需要知道子进程的退出状态,完成的任务结果如何。
3、父进程通过进程等待的方式,回收子进程资源,获取子进程退出状态。
函数原型:pid_t wait(int *status)
返回值:成功返回被等待进程的pid;失败返回-1;
参数:输出型参数,获取子进程的退出状态,不关心可以设置为NULL;
status&0x7f==0:表示代码执行完了,正常退出;
status&0x7f!=0:表示异常退出,具体值表示使该进程退出的信号的编码。
status>>8 & 0xff的值表示子进程的退出码。
调用wait函数会发生什么?
1. 如果有子进程在运行,父进程进入阻塞状态(可以理解为什么事情都没有做,一直在检测子进程是否在运行)
2.如果父进程在调用wait前子进程已经终止,wait可立即获得子进程的终止状态(退出码,退出信息),子进程的终止状态是体现在status参数上的,另外wait还会返回所终止的子进程的标识符。
3.如果当前没有子进程,则会出错返回-1。
4.如果有一个子进程终止,那么wait便返回。
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<sys/types.h> 4 #include<sys/wait.h> 5 6 int main() 7 { 8 int ret=fork(); 9 if(ret>0){ 10 int status=0; 11 int wait_id = wait(&status); 12 if(wait_id>0){ 13 printf("child has success dead!,id=%d\n",wait_id); 14 }else{ 15 printf("child has false dead!,%d\n",wait_id); 16 } 17 }else if(ret==0){ 18 printf("I am child,id=%d\n",getpid()); 19 sleep(5); 20 exit(0); 21 }else{ 22 perror("fork"); 23 } 24 return 0; 25 }
waitpid函数:也是创建进程,用法跟wait相似;
函数原型:pid_t waitpid(pid_t pid,int *status,int options)
pid:检测子进程的pid
status:子进程的终止状态,如果不是空指针,则终止进程的终止信息就存放在它所指向的单元内。不关心终止状态可以将status制成NULL。
options:指定参数,默认情况下waitpid与wait做的事情都是一样的,为阻塞式监测子进程终止状态;当options=WNOHANG时,此时为非阻塞方式,就是监测时如果子进程没有终止,调用者可以做其他事情,另外还有两个参数分别为WCONTINUED和WUNTRACED,这两个参数是跟作业控制有关的。
结果:
非阻塞等待:
结果:
WNOHANHG:若子进程没有结果,waipid返回0,不予等待,若正常结束,则返回该子进程的pid。
WIFEXITED(status):表示若为正常终止子进程返回的状态,则为真(查看进程是否是正常退出);
WEXITSTATUS(status):若WIFEXITED非零,提取子进程的退出码(查看进程退出码)。
进程终止—_exit()和exit()
查看进程退出码: echo $?
#include<unistd.h>void _exit(int status)参数:status定义了程序的终止状态,父进程通过wait获取该值。#include<unistd.h>void exit(int statsu)
_exit()—系统调用 exit()— 库函数
exit()做的三件事:
1,执行用户通过atexit或者on_exit定义的清理函数
2,关闭所有打开流,所有的缓存数据均被写入。
3,调用_exit;
思考题:vfork创建的子进程, 直接return为什么会出现崩溃?
结束子进程的调用是exit()而不是return,如果你在vfork中return了,那么,这就意味main()函数return了,注意因为函数栈父子进程共享,所以整个程序的栈就出现问题了。
- 【linux】进程创建、等待、终止
- linux下进程的状态,创建,替换,等待,终止
- 进程控制(上):进程创建,进程等待,进程终止
- Linux 线程(创建/等待/终止)
- Linux 线程(创建/等待/终止)
- linux线程(创建,等待,终止)
- Linux 线程(创建/等待/终止)
- 等待进程终止WaitForSingleObject()
- 进程等待与终止
- Linux C编程--进程介绍3--进程终止和等待
- Linux C编程--进程介绍3--进程终止和等待
- Linux C编程--进程介绍3--进程终止和等待
- 线程创建、等待、终止
- linux创建进程和等待进程退出
- 【Linux】线程总结:初识、创建、等待、终止、分离
- Linux之线程的创建、等待、终止及分离
- Linux-线程(一)创建 终止 等待线程
- 进程终止及等待相关
- 3年工作经验的程序员应该具备的技能
- Spring源码阅读——Bean的加载和获取过程
- 分布式ID生成服务
- 1.1.搭建Spring框架
- 在树莓派上安装mysql/MariaDB
- 【linux】进程创建、等待、终止
- Python3与OpenCV3.3 图像处理(十六)--图像金字塔
- IT的道德与伦理
- PyDev+Eclipse离线配置Python开发环境
- MySQL配置局域网内所有的用户可以连接
- JAVA语言特性笔记
- 洛谷P1197 [JSOI2008]星球大战
- spring 所有bean 加载顺序
- huffman编码