前言
Linux进程由进程启动,所有进程都应该有父进程。Linux系统中的进程结构类似树形结构,使用pstree命令可以查看当前系统中的进程树。进程树的顶端是进程init,它是系统启动后创建的第一个进程,负责启动getty进程、设置进程运行级别和回收孤儿进程等,是所有进程的祖先。
Linux系统中对进程的控制主要包括:进程创建、进程任务转变、进程同步和退出进程。Linux提供了一些与进程控制相关的接口,常用的接口为fork()、exex函数族、wait()、exit()。
这节课通过fork()函数来学习进程控制。
一、进程控制
1.创建一个进程
Linux使用fork()函数创建进程。fork函数是Linux多任务系统实现的基础,它包含在函数库unistd.h中,其函数声明如下:
#include <unistd.h>
pid_t fork(void);
完整代码见案例1
2.创建多个进程
对案例1中的代码进行修改,使用以下代码替代案例1中第七行的代码:
int i;
for(i = 0;i < 2;i ++){
pid = fork();
}
完整代码见案例2
3.进程的执行顺序
在案例1中,父进程先于子进程终止,子进程变为“孤儿进程”,后由进程init接收;在案例2中,创建了2个子进程,这2个子进程与父进程共同竞争资源。3个进程使用CPU的顺序不确定,由此子进程的编号不是递增关系,父进程在子进程尚未全部终止前便终止。另外,父进程是一个前台进程。当它终止退出后,会释放命令提示符,输出当前工作路径及终端提示符,但此时尚有子进程仍在执行,终端仍有信息输出,因此命令提示符会出现在输出结果最后一行的开头。
解决这种问题的方法不止一种,较为容易理解的方法是:使用sleep()函数,暂缓进程执行。
完整代码见案例3
二、案例
1.案例1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){//of main
pid_t pid;
pid = fork();//调用fork()函数创建子进程
if(pid == -1){//of if //创建失败
perror("fork error");
exit(1);//退出进程,指定返回值1
}
else if(pid > 0){//父进程
printf("parent process,pid = %d,ppid = %d\n",getpid(),getppid());
}
else if(pid == 0){//创建成功——子进程
printf("child process,pid = %d,ppid = %d\n",getpid(),getppid());
}
printf("........finish........\n");
return 0;
}
运行结果:
2.案例2
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){//of main
pid_t pid;
int i;
for(i = 0;i < 2;i ++){//of for //循环创建进程
if((pid = fork()) == 0)//of if //若当前进程为子进程,便跳出循环
break;
}
if(pid == -1){//of if
perror("fork error");
exit(1);
}
else if(pid > 0){//父进程
printf("parent process,pid = %d,ppid = %d\n",getpid(),getppid());
}
else if(pid == 0){//子进程
printf("I am child = %d,pid = %d,ppid = %d\n",i+1,getpid(),getppid());
}
printf("........finish........\n");
return 0;
}
运行结果:
2.案例3
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){//of main
pid_t pid;
int i;
for(i = 0;i < 2;i ++){//of for
if((pid = fork() == 0)//of if
break;
}
if(pid == -1){//of if
perror("fork error");
exit(1);
}
else if(pid > 0){
sleep(2);
printf("parent process,pid = %d,ppid = %d\n",getpid(),getppid());
}
else if(pid == 0){
sleep(i);
printf("I am child = %d,pid = %d,ppid = %d\n",i+1,getpid(),getppid());
}
printf("........finish........\n");
return 0;
}
运行结果:
总结
本节课通过三个案例对Linux的进程管理有了初步的认识,了解了init进程、孤儿进程的概念等,同样优先级的进程竞争系统资源,他们之间的执行顺序是无序的。