操作系统实验二:进程控制

操作系统实验二:进程控制

1、找父进程并构建进程树

打开一个vi进程。
在这里插入图片描述
新开起一终端,通过ps -C vips -e | grep vi命令,显示名字为vi的进程。
在这里插入图片描述
ps -C vi只显示名字为vi的进程信息
在这里插入图片描述
ps -e | grep vi则显示名字里带有vi的进程
grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。
可以看到名字为vi的进程的信息,进程号为2721

寻找vi进程的父进程,直到init进程为止。
linux控制台下输入ps -ef | grep 关键字可以查看是否有相应的进程启动信息中包含关键字。
在这里插入图片描述
在这里插入图片描述

进程树

vi->bash->gnome-terminal-server->upstart --user->lightdm --session-child 12 19->lightdm->init auto noprompt

由pstree命令的得到的进程树
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看出两种方法得到的进程树相同

2、编写程序,首先使用fork系统调用,创建子进程。

在父进程中继续执行空循环操作;在子进程中调用exec打开vi编辑器。

//fork1.c
#include <unistd.h>  
#include <sys/types.h>
#include <stdio.h>   
int main ()   
{   
    pid_t fpid; //fpid表示fork函数返回的值   
    fpid=fork();   
    if (fpid < 0)   
        printf("error in fork!");   
    else if (fpid == 0) {  
        printf("Child process is running\n");   
        printf("Execve pid = %d ,parentpid = %d\n",getpid(),getppid());   
        printf("Execve uid = %d ,gid =%d\n",getuid(),getgid());   
        execlp("vi",0); 
    }  
    else {  
        while(1){
        }
    }  
    return 0;  
}  

运行结果,子进程打开了vi
在这里插入图片描述
然后在另外一个终端中
通过ps –Al命令,查看vi进程及其父进程的运行状态

在这里插入图片描述
在这里插入图片描述

参数意义
F程序的flag
S程序的运行状态
UID用户id
PID进程id
PPID当前进程的父进程id
CCPU资源使用的百分比
PRI优先级
NINice值,负值表示高优先级,正值表示低优先级
ADDR指出程序在内存的哪个部分
SZ使用内存的大小
WCHAN程序是否仍在运行,若为-则正在运行
TTY启动进程的终端名
TIME进程使用CPU的总时间
CMD命令名

ps aux命令
显示所有用户的进程,但该命令无法查看父进程的pid
在这里插入图片描述
在这里插入图片描述

参数意义
USER进程拥有者
PID进程id
%CPU上次更新到现在的CPU时间占用百分比
%MEM进程使用的物理内存百分比
VSZ占用的虚拟内存大小
RSS占用的内存大小
TTY终端的次要装置号码
STATD代表不可中断 R代表正在执行 S代表静止状态 T代表暂停执行 Z代表僵死状态
START进程开始的时间
TIME进程占用CPU的时间
COMMAND命令名

top命令
常用于监控linux的系统状况,显示系统运行时间和平均负载,系统现在进程运行情况,CPU状态,内存状态等信息。
在这里插入图片描述
通过内部命令P,使所有进程按照CPU占用率排序
在这里插入图片描述

3、使用fork系统调用,创建如下进程树,并使每个进程输出自己的ID和父进程的ID。

在这里插入图片描述
(csdn贴代码老出错,就不贴了)
去GitHub的直通车

在这里插入图片描述
在这里插入图片描述
第一个P1即为fork2进程,pid2878,父是2867,是bash

第二个P1是fork2建立的子进程,pid2879,父是2878
P2 pid 2880 父是P1 2879
P3 pid 2881 父是P1 2879
P4 pid 2882 父是P2 2880
P5 pid 2889 父是P2 2880
进程树

bash->fork2->P1->P3
               ->P2->P4
                   ->P5

4、修改上述进程树中的进程,使得所有进程都循环输出自己的ID和父进程的ID。

(同理不贴代码了)
代码直通车
这里每次输出后都加了sleep(10),以及p1输出前加空格,方便观察和截图
在这里插入图片描述

终止p2进程,观察p1、p3、p4、p5进程的运行状态和其他相关参数有何改变。
采用kill -9
另开一个进程,使用kill -9 2962命令后
在这里插入图片描述在这里插入图片描述
可以看到进程p2没有了,p1、p3没有变化,但p4、p5(p2的子进程)依旧在,不过父进程变成了1540,也就是upstart --user

自己正常退出exit()
代码直通车
这里在p2的片段进行修改,在输出后加了exit(0)

 printf("Node p2 pid %d, it's parent pid %d.\n",getpid(),getppid());      
 sleep(10);
 printf("P2通过exit()自己正常退出\n");     
 exit(0);

在这里插入图片描述

在这里插入图片描述
结果相同

段错误退出
代码直通车
在p2的片段进行修改,使用空指针造成段错误

printf("Node p2 pid %d, it's parent pid %d.\n",getpid(),getppid());      
sleep(10);
printf("P2发生段错误退出\n");
unsigned char *ptr = 0x00;   
*ptr = 0x00;

在这里插入图片描述
可以看到,结果是进程p2消失,p1、p3无变化,p4、p5的父进程发生的更改,结果相同。

5、总结

本实验重点在于进程树的创建,我在写的时候在各进程的关系上绕晕了一段时间。
通过实验对fork函数和进程的理解更深了。
最后,本实验代码均上传至GitHub。
点这里直接进

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值