计算机系统基础-OS实验方案.docx
文本预览下载声明
计算机系统基础课程实验指导-OS一、实验目的调用fork函数创建子进程,观察父子进程的并发执行过程,区别顺序执行和并发执行;明确进程和程序的区别;调用pipe函数在父子进程间建立管道通信,掌握linux管道通信的机制;(可选)二、实验环境操作系统: Linux编译器: GCC编程语言: C语言三、实验准备:1. 熟悉Linux操作系统,掌握Shell的基本命令;2. 会使用Vi编辑器;打开:vi 文件名 ;进入输入模式:在指令模式按i键;保存退出:按esc键,:wq3. 掌握GCC编译器的基本用法;gcc 源程序 –o 可执行文件4.复习进程的基本概念;4. 预习如下系统调用的含义与用法:(具体说明详见相关文档)fork函数所需头文件#include sys/types.h?// 提供类型 pid_t 的定义#include unistd.h函数说明建立一个新的进程函数原型pid_t fork(void)函数返回值0:返回给子进程子进程的ID(大于0的整数):返回给父进程-1:出错,返回给父进程,错误原因存于errno中错误代码EAGAIN:内存不足ENOMEM:内存不足,无法配置核心所需的数据结构空间getpid和getppid函数头文件#include sys/types.h#include unistd.h函数说明函数原型返回值pid_t getpid(void )进程IDpid_t getppid(void )父进程IDpipe函数所需头文件#includeunistd.h函数说明建立一个管道函数原型int pipe(int filedes[2])函数返回值0:成功-1:出错,,错误原因存于errno中错误代码EMFILE 进程已用完文件描述词最大量。EFAULT 参数 filedes 数组地址不合法。ENFILE 系统已无文件描述词可用。execv函数所需头文件#include unistd.h函数说明执行文件函数原型int execv(const char *path, char *const argv[])函数返回值成功:函数不会返回出错:返回-1,失败原因记录在error中dup2函数所需头文件#include unistd.h函数说明复制一个文件的描述符函数原型?int?dup2(?int?oldfd,?int?targetfd?)函数返回值成功:函数返回出错:返回-1,失败原因记录在error中四、实验内容及步骤:按照下述步骤进行实验:创建一个新进程。在Vi编辑器中,编辑如下代码,其主要功能是使用fork( )创建一个新进程:#include stdio.h#include sys/types.h#include unistd.hint main() { pid_t pid; int x = 1; pid = fork(); if (pid == 0) { /* Child */printf(hello ,child : x=%d\n, ++x);return 0; }/* Parent */if(pid0)printf(hello, parent: x=%d\n, --x); return 0;}在Linux上编译并运行这个程序,观察得到的结果。多次运行,看看结果有什么不同,尝试解释这种现象。理解fork生成新进程时父子进程各自的行为:#include stdio.h#include sys/types.h#include unistd.hint main() { fork();fork();printf(“hello, world\n”);return 0;}在Linux上编译运行这个程序,观察得到的结果会输出几次hello world,并解释为什么。编制一段程序,使用系统调用fork()创建三个子进程,在各个子进程中再使用系统调用fork()进一步创建子进程,如此重复,构造一棵具有图1形状的进程家族树。分别使用系统调用getpid()和getppid()获取当前进程和父进程的进程标识号并分别填入图1中相应的进程节点;。图1 进程家族树在父子进程之间建立管道进行通信。调用pipe函数,在父进程和子进程间建立一条管道进行通信。示例如下:……int pipe_fd[2];char r_buf[10],w_buf[6];int r_num;if(pipe(pipe_fd)0) //建立管道{printf(pipe create error!\n);return 0;}printf(pipe_fd[0] is %d,pipe_fd[1] is %d\n,pipe_fd[0],pipe_fd[1]);if(pid=fork()==0) //子进程{close(pipe_fd[1]); //关闭写端
显示全部