**
什么是进程?
**
- 正在执行的程序
- 正在计算机上执行的程序实例
- 能分配给处理器并由处理器执行的实体
- 具有以下特征的活动单元:一组指令序列的执行 、一个当前状态和相关的系统资源集进程
进程的创建
fork/vfork函数
fork函数
利用fork函数创建一个新进程,新进程为子进程,原进程为父进程。
#include <unistd.h>
pid_t fork(void);
返回值:失败返回-1,成功子进程返回0,父进程返回子进程id
1 #include<stdio.h>
2 #include<unistd.h>
3
4 int main(){
5
6 int i = 100;
7 pid_t pid = fork();
8 if(pid > 0){ //父进程空间
9 i=200;
10 printf("I am father,pid is:%d,i=%d\n",getpid(),i);
11 }
12 else if (pid==0){ //子进程空间
13 i++;
14 printf("I am child,pid is:%d,i=%d\n",getpid(),i);
15 }
16 else{
17 perror("fork");
18 }
19
20 return 0;
21
22 }
运行结果:
通过以上的程序我们可以发现:
父子进程代码共享,如果父子不进行写入时,数据也是共享的,如果有一方进行写入,就各自拷贝一份副本,利用了 写时拷贝的机制。另外,两个进程处于独立的空间,它们各自执行自己的东西,不产生冲突,而至于是子进程还是父进程先执行,这没有确切的规定,是随机的.
fork出错可能有两种原因:
1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。
2)系统内存不足,这时errno的值被设置为ENOMEM。
vfork函数
vfork函数同样也可以用来创建进程,与fork不同的是,vfork创建的子进程,子进程和父进程共享地址空间,并保证子进程先运行,当它调用exec或(exit)之后父进程才可能被调度
进程终止
进程的一般退出场景
1、代码运行结束,结果正确
2、代码运行结束,结果不正确
3、代码异常终止
进程常见的退出方法:
1、main函数返回
2、调用exit
3、调用_exit
注:我们可以通过echo $?查看进程退出码
_exit函数和exit函数
#include<unistd.h>
void _exit(int status);
#include<stdlib.h>
void exit(int status);
运行结果:
运行结果:
这两个程序,程序2输出的是两句话,而程序1只输出了一句话。原因就是因为最后一句话上没有加上特殊的字符,如换行和文件结束符,因为这个时候文件是存放在缓冲区的,这个例子中文件就是存放打开的显示设备的缓冲区中的,因为输出函数要写入,首先要进行系统调用,这个时候系统会打开显示设备的缓冲区,而exit的作用就是结束,清理,就是说先检查缓冲区,把没有写入的数据写入到文件,而_exit是立刻关闭文件,文件缓冲区的内容也就消失了,这个时候就不可能再输出到显示设备了。
总结:exit()与_exit()区别:
1、_exit()直接是一个sys_exit系统调用,而exit()则通常是普通函数库中的一个函数。
2、exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,而_exit()函数直接退出。
进程等待
**
进程等待的必要性:
1、子进程退出,父进程如果不管不顾,可能造成“僵尸进程”,从而引发内存泄露
僵尸进程:https://blog.csdn.net/rae8023/article/details/71843128
2、我们必需通过进程等待的方式获得子进程的退出信息
3、可以决定谁先退出,保证父子退出顺序
进程的等待的方法:
wait方法
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int* status);
成功返回等待进程的pid,失败返回-1
waitpid方法
#include<sys/types.h>
#include<sys/wait.h>
pid_t waitpid(pid_t,int* status,int options);
参数:pid: pid=-1 等待任意一个子进程,相当于wait
pid>0 等待进程id与pid相等的子进程
status: WIFEXITED(status):正常终止子进程返回的状态,为真
WEXITSTATUS(status):若WIFEXITED为0,提取进程退出码
options: WNOHANG:若pid指定的子进程没有结束,则waitpid()函数返回0,不欲以等待,正常结束,返回子进程pid
status
输出型参数,由操作系统填充,如果传递NULL,表示不关心子进程的退出信息,否则操作系统会根据该参数,将进程的退出信息反馈给父进程。