操作系统第二次试验报告:创建进程
- 朱笃信
- 201821121021
- 计算1811
1. 编写程序
代码源码:
1 #include<unistd.h> 2 #include<stdio.h> 3 int main() 4 { 5 pid_t pid; 6 int i=0; 7 printf("parent's pid:%d\n",getpid()); //打印父进程的pid 8 for(i=0;i<2;i++){ 9 if(pid=fork()==0) 10 { 11 printf("child's pid:%d,ppid:%d\n",getpid(),getppid()); //打印各个子进程的pid及其对应的ppid 12 return 0; 13 } 14 } 15 sleep(10); 16 return 0; 17 }
执行效果:
2. 打印进程树
进程树显示结果:
3. 解读进程相关信息
(1) ps -ef
显示结果:
字段解析:(图中显示的各个数据与下述字段相对应)
- UID:用户ID(此处为朱笃信)
- PID:进程ID(此处为29370等等)
- PPID:父进程ID(此处为21799等等)
- C:占用CPU百分比(全0那列)
- STIME:start time进程开始时间(17:48那列)
- TTY:与进程关联的终端(pts/3)
- TIME:进程使用的总cpu时间(00:00:00)
- CMD:正在执行的命令行命令(最后一列)
(2) ps -aux
显示结果:
字段解析:(图中显示的各个数据与下述字段相对应,共11列)
- USER:用户名(zhuduxin)
- PID:进程ID(此处为29370等等)
- %CPU:CPU占比(0.0)
- %MEN:内存占比(0.0)
- VSZ:虚拟记忆体占用大小
- RSS:记忆体占用大小
- TTY:与进程关联的终端
- STAT:该行程的状态,linux的进程有5种状态:
- D 不可中断 uninterruptible sleep (usually IO)
- R 运行 runnable (on run queue)
- S 中断 sleeping
- T 停止 traced or stopped
- Z 僵死 a defunct (”zombie”) process
- START:同STIME,进程开始时间
- TIME:进程使用的总cpu时间(00:00:00)
- COMMAND:与CMD含义相同,正在执行的命令行命令
4. 通过该实验产生新的疑问及解答
一个父进程创建两个子进程能否通过先后创建的方式来执行?
答案是可以,但是同时会产生孙进程。
测试代码如下:
1 #include<unistd.h> 2 #include<stdio.h> 3 #include<stdlib.h> 4 int main(){ 5 pid_t pid; 6 printf("parent's pid:%d\n",getpid()); 7 sleep(2); 8 pid=fork(); 9 if(pid<0){ 10 perror("fork failed"); 11 exit(1); 12 } 13 else if(pid==0){ 14 printf("child1's pid:%d,ppid:%d\n",getpid(),getppid()); 15 } 16 else{ 17 printf("the first was parent,and pid:%d,ppid:%d\n",getpid(),getppid()); 18 } 19 20 pid=fork(); 21 if(pid<0){ 22 perror("fork failed"); 23 exit(1); 24 } 25 else if(pid==0){ 26 printf("child2's pid:%d,ppid:%d\n",getpid(),getppid()); 27 } 28 else{ 29 printf("the second was parent,and pid:%d,ppid:%d\n",getpid(),getppid()); 30 } 31 sleep(10); 32 return 0; 33 }
测试结果:
对执行结果的判断:
前三行的输出结果都表示当前进程为该代码执行时的对应进程,可以理解为,父进程(4237)在创建子进程(4238与4239)后,仍会执行后续代码,故而显示为父进程。
第四行与第五行显示为子进程,但是先输出了第二个判断的结果,个人理解为该情况是由于第二个生成子进程(4239)的fork在第一个未执行完便生成,打断了第一个子进程(4238)的输出。
第一个子进程(4238)创建完成后,执行了后续代码,即子进程的创建会继续其后的逻辑代码,那么在执行到第二个判断时,会再一次执行fork,从而产生孙进程(4240),并且在孙进程(4240)完成创建前,先执行了,判断语句,所以会有第六行的“the second was parent,and pid:4238,ppid:4237”输出。
而第二个子进程(4239)执行完,便没有后续语句可供执行,所以不会再显示类似第一个子进程的情况。