进程控制
1.实验目的:
加深对进程概念的理解,明确进程和程序的区别。
掌握Linux系统中的进程创建,管理和删除等操作。
熟悉使用Linux下的命令和工具,如man, find, grep, whereis, ps, pgrep, kill, ptree, top, vim, gcc,gdb, 管道|等。
2.基础知识:
进程的创建
Linux中,载入内存并执行程序映像的操作与创建一个新进程的操作是分离的。将程序映像载入内存,并开始运行它,这个过程称为运行一个新的程序,相应的系统调用称为exec系统调用。而创建一个新的进程的系统调用是fork系统调用。
exec系统调用
#include <unistd.h>
int execl (const char *path, const char *arg,…);
execl()将path所指路径的映像载入内存,arg是它的第一个参数。参数可变长。参数列表必须以NULL结尾。
通常execl()不会返回。成功的调用会以跳到新的程序入口点作为结束。发生错误时,execl()返回-1,并设置errno值。
例 编辑/home/kidd/hooks.txt:
int ret;
ret = execl (”/bin/vi”, ”vi”,”/home/kidd/hooks.txt”, NULL);
if (ret == -1)
perror (”execl”);
fork系统调用
#include <sys/types.h>
#include <unistd.h>
pid_t fork (void);
成功调用fork()会创建一个新的进程,它与调用fork()的进程大致相同。发生错误时,fork()返回-1,并设置errno值。
例:
pid_t pid;
pid = fork ();
if (pid > 0)
printf (”I am the parent of pid=%d!\n”, pid);
else if (!pid)
printf (”I am the baby!\n”);
else if (pid == -1)
perror (”fork”);
终止进程
exit()系统调用:
#include <stdlib.h>
void exit (int status);
进程挂起
pause() 系统调用:
int pause( void );
函数pause会把进程挂起,直到接收到信号。在信号接收后,进程会从pause函数中退出,继续运行。
wait(等待子进程中断或结束)
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait (int * status);
wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。
如果在调用 wait()时子进程已经结束,则wait()会立即返回子进程结束状态值。
子进程的结束状态值会由参数status返回,而子进程的进程识别码也会一起返回。
如果不在意结束状态值,则参数status可以设成 NULL。
VIM常用命令速查
3.实验题目:
根据课堂所学内容和基础知识介绍,完成实验题目。
1、打开一个vi进程。通过ps命令以及选择合适的参数,只显示名字为vi的进程。寻找vi进程的父进程,直到init进程为止。记录过程中所有进程的ID和父进程ID。将得到的进程树和由pstree命令的得到的进程树进行比较。
2、编写程序,首先使用fork系统调用,创建子进程。在父进程中继续执行空循环操作;在子进程中调用exec打开vi编辑器。然后在另外一个终端中,通过ps –Al命令、ps aux或者top等命令,查看vi进程及其父进程的运行状态,理解每个参数所表达的意义。选择合适的命令参数,对所有进程按照cpu占用率排序。
3、使用fork系统调用,创建如下进程树,并使每个进程输出自己的ID和父进程的ID。观察进程的执行顺序和运行状态的变化。
4、修改上述进程树中的进程,使得所有进程都循环输出自己的ID和父进程的ID。然后终止p2进程(分别采用kill -9 、自己正常退出exit()、段错误退出),观察p1、p3、p4、p5进程的运行状态和其他相关参数有何改变。
实验报告:
Task 1:打开一个vi进程。通过ps命令以及选择合适的参数,只显示名字为vi的进程。寻找vi进程的父进程,直到init进程为止。记录过程中所有进程的ID和父进程ID。将得到的进程树和由pstree命令的得到的进程树进行比较。
(1)打开一个终端,输入vi,回车打开一个vi进程;
(2)打开另一个终端,通过 ps -A 显示所有进程;
(3)通过 ps aux |grep vi 命令显示名字为vi的进程;
由上图可知vi进程的PID为2875;
(4)通过命令 ps -ef | grep PID 寻找vi 的父进程,直到init进程;
在这里插入图片描述可知:
2875->2865->2859->1849->1150->871->1
ps -ef|grep详解
ps命令将某个进程显示出来;
grep命令是查找;
中间的|是管道命令 是指ps命令与grep同时执行;
PS是LINUX下最常用的也是非常强大的进程查看命令;
grep命令是查找,是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。
以下这条命令是检查java 进程是否存在:ps -ef |grep java
字段含义如下:
UID PID PPID C STIME TTY TIME CMD
zzw 14124 13991 0 00:38 pts/0 00:00:00 grep --color=auto dae
UID:程序被该 UID 所拥有
PID:就是这个程序的 ID
PPID:则是其上级父程序的ID
C:CPU使用的资源百分比
STIME:系统启动时间
TTY:登入者的终端机位置
TIME:使用掉的CPU时间。
CMD:所下达的是什么指令
(5)通过命令 pstree PID得到进程树;(pstree -p为查询整个进程树)
对比发现两种方式所得结果一样;
2、编写程序,首先使用fork系统调用,创建子进程。在父进程中继续执行空循环操作;在子进程中调用exec打开vi编辑器。然后在另外一个终端中,通过ps –Al命令、ps aux或者top等命令,查看vi进程及其父进程的运行状态,理解每个参数所表达的意义。选择合适的命令参数,对所有进程按照cpu占用率排序。
程序代码截图
ps –Al命令查看vi进程及其父进程的运行状态:
所有进程按照cpu占用率排序:
参数命令解析:
PID 进程id
PPID 父进程id
RUSER Real user name
UID 进程所有者的用户id
USER 进程所有者的用户名
GROUP 进程所有者的组名
TTY 启动进程的终端名。不是从终端启动的进程则显示为 ?
PR 优先级
NI nice值。负值表示高优先级,正值表示低优先级
P 最后使用的CPU,仅在多CPU环境下有意义
%CPU 上次更新到现在的CPU时间占用百分比
TIME 进程使用的CPU时间总计,单位秒
TIME+ 进程使用的CPU时间总计,单位1/100秒
%MEM 进程使用的物理内存百分比
VIRT 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
SWAP 进程使用的虚拟内存中,被换出的大小,单位kb。
RES 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
CODE 可执行代码占用的物理内存大小,单位kb
DATA 可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
SHR 共享内存大小,单位kb
nFLT 页面错误次数
nDRT 最后一次写入到现在,被修改过的页面数。
3、使用fork系统调用,创建如下进程树,并使每个进程输出自己的ID和父进程的ID。观察进程的执行顺序和运行状态的变化。
程序代码截图
程序输出结果
执行顺序为:P1->P2->P4->P5->P3
4、修改上述进程树中的进程,使得所有进程都循环输出自己的ID和父进程的ID。然后终止p2进程(分别采用kill -9 、自己正常退出exit()、段错误退出),观察p1、p3、p4、p5进程的运行状态和其他相关参数有何改变。
程序代码截图
程序输出结果
kill -9 终止P2 进程结果
P2 进程被杀死后,P4、P5 进程还在,不过父进程改变了。P2 进程的STAT状态由S+变为Z+;
自己正常退出exit()程序结果
自己正常退出exit():利用i 变量设置循环5次后执行exit(0),退出。
段错误退出程序结果
段错误退出部分代码更改
段错误注解:
段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gd tr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的 gdt表,后13位保存 相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向 的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起 始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。
常用段错误:
1,int main(void){
char*s =“hello world”;
s =‘H’;
}
被装载时,系统把“hello world” 连同其它的字符串和const型数据放入到内存的只读区。执行时,一个变量s被设为指向该字符串的位置,当再试图向该位置写时,就会产生段错误。
2,
intptr = NULL;
*ptr =1;
因为该代码只创建了一个空指针,并没有指向一个具体空间,当赋值时,产生段错误。
3,
int main(void){
main();
return0;
}
无限递归,这会导致栈溢出,也会产生段错误。
如需相关资料,请查阅:实验资料(github)
欢迎使用Markdown编辑器
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
新的改变
我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:
- 全新的界面设计 ,将会带来全新的写作体验;
- 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
- 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
- 全新的 KaTeX数学公式 语法;
- 增加了支持甘特图的mermaid语法1 功能;
- 增加了 多屏幕编辑 Markdown文章功能;
- 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
- 增加了 检查列表 功能。
功能快捷键
撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
合理的创建标题,有助于目录的生成
直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC
语法后生成一个完美的目录。
如何改变文本的样式
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本
引用文本
H2O is是液体。
210 运算结果是 1024.
插入链接与图片
链接: link.
图片:
带尺寸的图片:
居中的图片:
居中并且带尺寸的图片:
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
// An highlighted block
var foo = 'bar';
生成一个适合你的列表
- 项目
- 项目
- 项目
- 项目
- 项目1
- 项目2
- 项目3
- 计划任务
- 完成任务
创建一个表格
一个简单的表格是这么创建的:
项目 | Value |
---|---|
电脑 | $1600 |
手机 | $12 |
导管 | $1 |
设定内容居中、居左、居右
使用:---------:
居中
使用:----------
居左
使用----------:
居右
第一列 | 第二列 | 第三列 |
---|---|---|
第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
TYPE | ASCII | HTML |
---|---|---|
Single backticks | 'Isn't this fun?' | ‘Isn’t this fun?’ |
Quotes | "Isn't this fun?" | “Isn’t this fun?” |
Dashes | -- is en-dash, --- is em-dash | – is en-dash, — is em-dash |
创建一个自定义列表
-
Markdown
- Text-to- HTML conversion tool Authors
- John
- Luke
如何创建一个注脚
一个具有注脚的文本。2
注释也是必不可少的
Markdown将文本转换为 HTML。
KaTeX数学公式
您可以使用渲染LaTeX数学表达式 KaTeX:
Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n−1)!∀n∈N 是通过欧拉积分
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
你可以找到更多关于的信息 LaTeX 数学表达式here.
新的甘特图功能,丰富你的文章
- 关于 甘特图 语法,参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图::
这将产生一个流程图。:
- 关于 Mermaid 语法,参考 这儿,
FLowchart流程图
我们依旧会支持flowchart的流程图:
- 关于 Flowchart流程图 语法,参考 这儿.
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件或者.html文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
注脚的解释 ↩︎