进程管理实验
一、实验目的加深对进程概念的理解,明确进程和程序的区别。进一步认识并发执行的实质。熟悉fork函数的使用。二、实验软硬件要求1、CPU:P4 1.6GHz 内存:1G2、Windows7操作平台3、VMware虚拟机(安装有Ubuntu操作系统)三、实验预习在Linux下一个进程在内存里有三部分的数据,就是"代码段"、"堆栈段"和"数据段"。"代码段",顾名思义,就是存放了程序代码的数据,假如机器
目录
1、试运行如下一段代码,观察并截屏纪录屏幕上的显示结果,并分析原因。
2)实验分析与结果:(对实验结果的分析推荐用进程关系图表示)编辑
3、修改已经编好的程序,将每个进程输出一个字符改为每个进程循环输出五句话,再观察程序执行时屏幕上出现的现象,并分析原因。
4、如果第三步的实验程序中使用调用lockf(1,1,0)和lockf(1,0,0)来给每一个子进程加锁(锁定屏幕输出)和解锁,可以实现进程之间的互斥,观察并分析出现的现象。
问题2:如果将上面程序中的fork 改成vfork,运行结果是多少呢?
一、实验目的
- 加深对进程概念的理解,明确进程和程序的区别。
- 进一步认识并发执行的实质。
- 熟悉fork函数的使用。
二、实验软硬件要求
1、CPU:P4 1.6GHz 内存:1G
2、Windows7操作平台
3、VMware虚拟机(安装有Ubuntu操作系统)
三、实验预习
在Linux下一个进程在内存里有三部分的数据,就是"代码段"、"堆栈段"和"数据段"。"代码段",顾名思义,就是存放了程序代码的数据,假如机器中有数个进程运行相同的一个程序,那么它们就可以使用相同的代码段。"堆栈段"存放的就是子程序的返回地址、子程序的参数以及程序的局部变量。而数据段则存放程序的全局变量,常数以及动态数据分配的数据空间(比如用malloc之类的函数取得的空间)。系统如果同时运行数个相同的程序,它们之间就不能使用同一个堆栈段和数据段。
一个程序一旦调用fork函数,系统就为一个新的进程准备了前述三个段,首先,系统让新的进程与旧的进程使用同一个代码段,因为它们的程序还是相同的,对于数据段和堆栈段,系统则复制一份给新的进程,这样,父进程的所有数据都可以留给子进程,但是,子进程一旦开始运行,虽然它继承了父进程的一切数据,但实际上数据却已经分开,相互之间不再有影响了,也就是说,它们之间不再共享任何数据了。
因此,在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。至于fpid的值为什么在父子进程中不同。“其实就相当于链表,进程形成了链表,父进程的fpid(p 意味point)指向子进程的进程id, 因为子进程没有子进程,所以其fpid为0.
fork()函数一共有三种返回值:
a)在父进程中,fork返回新创建子进程的进程ID;
b)在子进程中,fork返回0;
c)如果出现错误,fork返回一个负值;
创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。
四、实验内容(实验步骤、测试数据等)
1、试运行如下一段代码,观察并截屏纪录屏幕上的显示结果,并分析原因。1)程序代码 |
2)实验分析与结果:(对实验结果的分析推荐用进程关系图表示)1.pid_t定义的类型都是进程号类型。这个语句的意思是定义了一个pid_t类型的变量pid,fork()函数返回一个进程号,这个进程号赋给了pid 2.PID(process ID): PID是程序被操作系统加载到内存成为进程后动态分配的资源。 每次程序执行的时候,操作系统都会重新加载,PID在每次加载的时候都是不同的。 3.PPID(parent process ID):PPID是程序的父进程号。 Fpid若不为0,则显示子进程的PID号 至于PID2607这里PPID号为什么不是2605,大抵是父进程先退出,那子进程就没有父进程了,成了孤儿进程,因此1427进程领养了2386。 至于为什么必须要领养,大抵是没有领养,就变成僵尸进程。 至于为什么是1427领养,大抵是1427进程当时正在运行。linux内核大概是设计成任何一个现成的进程都能领养。 |
2、编写一段源程序,使系统调用fork()创建两个子进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。试观察纪录屏幕上的显示结果,并分析原因。1)程序代码: |
2)实验分析与结果:If(fpid=fork())创建子进程成功 |
3、修改已经编好的程序,将每个进程输出一个字符改为每个进程循环输出五句话,再观察程序执行时屏幕上出现的现象,并分析原因。
成功创建一个进程,就循环输出五次一个字符。 |
4、如果第三步的实验程序中使用调用lockf(1,1,0)和lockf(1,0,0)来给每一个子进程加锁(锁定屏幕输出)和解锁,可以实现进程之间的互斥,观察并分析出现的现象。注意:关于lockf()在此题中的使用可参考下面的例子。 lockf()函数 利用系统调用lockf(fd,mode,size),对指定区域(有size指示)进行加锁或解锁,以实现进程的同步或互斥。 其中,fd是文件描述字; mode是锁定方式,mode=1表示加锁,mode=0表示解锁; size是指定文件fd的指定区域,用0表示从当前位置到文件结尾。 注:有些Linux系统是locking(fd,mode,size) |
5、关于vfork函数的使用问题1:打印出的值应该是多少呢?当是fork时,数据段中的cnt,父子进程互不影响,所以cnt=1。 问题2:如果将上面程序中的fork 改成vfork,运行结果是多少呢?vfork保证子进程先运行,在她调用exec或exit之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。这样上面程序中的fork()改成vfork()后,vfork()创建子进程并没有调用exec或exit,所以最终将导致死锁。 在关于子程序输出的代码进行修改,添加一个_exit(0)使其退出 子进程调用exec 或exit之前与父进程数据是共享的,所以子进程退出后把父进程的数据段count改成1了,子进程退出后,父进程又执行,最终就将count变成了2. 运行结果: 问题3:请对问题1和问题2输出的结果进行比较分析。 fork ():子进程拷贝父进程的数据段,代码段 vfork ():子进程与父进程共享数据段 具体分析写在各问题下。 |
五、实验体会
操作不够熟练,需要加强练习。
更多推荐
所有评论(0)