实验2Linux进程管理
实验2 Linux进程管理
实验目的
1、加深对进程概念的理解,明确进程和程序的区别
2、进一步认识并发执行的实质
3、分析进程争用资源的现象,学习解决进程互斥的方法
实验性质
验证性实验,必做,3课时
预习与实验要求
1、阅读Linux的sched.h源码文件,加深对进程概念的理解
2、阅读Linux的fork.c源码文件,分析进程的创建过程
要用到的系统调用
1、int fork 创建一个新进程
头文件:#include #include 返回值的意义:0,创建子进程,从子进程返回的id值 -1,创建失败 大于0,从父进程返回的子进程id值
2、lockf files, function, size 锁定/解锁文件或文件的某段
该函数的头文件为:#include
参数定义:int lockf int files, int function, long size
含义:files是文件描述符;
function为1(常量F_LOCK)表示互斥锁定,为0(常量F_ULOCK)表示解锁;
size是锁定或解锁的字节数,若用0,表示从文件的当前位置到文件尾。
实验内容
创建进程。
输入并运行下面的程序。思考为什么会输出两行信息。【建议用emacs或gedit编辑】
int main int pid;
pid fork ;
switch pid case -1: printf "fail to create process\n" ; return 1;
case 0: //对于子进程来讲,变量pid的值为0 printf "I'm son, my pid is %d, my father's pid is %d\n", getpid , getppid ; break;
default: //对于父进程来讲,pid记录了返回的子进程的ID,必然大于0 printf "I'm father, my pid is %d, my son's pid is %d\n", getpid , pid ; return 0; 输出结果并非是一行,而是2行。比如,结果可能是:
I'm son, my pid is 1860, my father's pid is 1859
I'm father, my pid is 1859, my son's pid is 1860
解释:
fork函数被调用一次但返回两次。两次返回的唯一区别:子进程中返回0值,父进程中返回子进程ID。
为什么返回两次?原因:linux将父进程的地址空间、数据空间、堆、栈等资源复制一份给子进程,子进程是父进程的副本,只有代码段是共享的。注意:由于在复制时复制了父进程的堆栈段,所以两个进程都停留在fork函数中,等待返回。不同的是,fork 返回给父进程的是新建子进程的ID,返回给子进程的是0。
如果对“返回”还难以理解,想一下学C语言时候的函数调用。函数调用时,将返回地址入栈,再将实参入栈。被调函数从栈中取出参数,赋值给形参,执行完后,取出返回地址,跳回去继续执行。
1、验证进程并发执行
编写一段程序,使用系统调用fork 创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每个进程在屏幕上显示一个字符串:父进程显示“parent is working”;两个子进程分别显示“son is working”和“daughter is working”。多运行几次该程序,观察屏幕上的显示结果,并分析原因。
文件名为a21.c
#include
main int p1,p2;
while p1 fork -1 ;/*创建子进程,将其ID号给p1,直到成功*/
if p1 0 printf “son is working\n” ;/*子进程返回的p1才为0,说明此时子进程执行*/
else /*p1 0,说明此p1是父进程函数调用返回的子进程的ID号*/
while p2 fork -1 ;/*创建子进程p2,将其ID号给p2,直到成功*/
if p2 0 printf “dauthter is working” ; /*子进程p2执行*/
else printf “parent” ; /*父进程执行*/ printf “share\n” ;/*3个进程共享的语句*/ 执行:用gcc a21.c –o a21.out编译,产生a21.out文件。在终端里输入./a21.out,并回车执行。看结果。再按向上箭头,并回车重复执行。看结果。如此多执行几次。
分析:可以认为,父进程和两个子进程有相同的代码。相当于,上述程序有3份在内存。它们并发执行,但它们返回的