软件c122郭嵘峥 125448
操作系统实验报告
2.3 Linux并发程序设计
(实验估计时间:90分钟)
? 背景知识 ? 实验目的
? 工具/准备工作 ? 实验内容与步骤
背景知识
管道是Linux中最常用的进程间通信IPC机制。利用管道时,一个进程的输出可成为另外一个进程的输入。当输入输出的数据量特别大时,这种IPC机制非常有用。可以想象,如果没有管道机制,而必须利用文件传递大量数据时,会造成许多空间和时间上的浪费。
在Linux中,通过将两个file结构指向同一个临时的索引节点,而两个索引节点又指向同一个物理页而实现管道。 实验目的
1) 通过在Linux进程之间进行的通信实例来学习并发程序设计的方法。 2) 通过Linux进程通信的程序设计与实现,进一步熟悉操作系统的进程概念,理解Linux进程管理概念。
3) 通过阅读和分析Linux实验程序,学习Linux程序设计、调试和运行的方法。 工具/准备工作
在开始本实验之前,请回顾教科书的相关内容。 需要准备一台运行Linux操作系统的计算机。 实验内容与步骤
并发程序的设计关键是使用创建进程的系统调用,使一个程序运行时可以生成几个同时运行的程序,如果程序中没有创建进程的动作则为顺序程序设计。
本实验中的并发程序例子完成两个程序child和father之间的数据传递工作,具体做法分为四步。
步骤1:编制并发程序pipeline.c。
单击红帽子,在“GNOME帮助”菜单中单击“附件”-“文本编辑器”命令,在文本编辑中键入程序并保存为pipeline.c。
软件c122郭嵘峥 125448
在该程序中定义管道和文件描述符,并且创建子进程child。该程序用到的系统调用有pipe() 、dup() 、fork() 、close、execl() 、exit,它们的功能分别是建立管道、复制文件描述符、创建进程并使子进程与父进程有相同的程序正文、关闭文件描述符、用指定文件覆盖调用程序、撤销当前进程。
清单4-5 pipeline.c
// 定义管道程序
# define STD_INPUT 0 // 定义标准输入设备描述符 # define STD_OUTPUT 1 // 定义标准输出设备描述符
int fd[2];
main() {
static char process1[]=\
pipe(fd); // 定义管道 pipeline(process1,process2); // 调用自定义函数pipeline() exit(1); // 程序结束
}
pipeline(char* process1,char* process2) {
int i; while ((i=fork())==-1); // 创建进程,直到创建成功为止 if (i) { close(fd[0]); // 关闭管道输入描述符 close(STD_OUTPUT); // 关闭标准输出描述符1 dup(fd[1]); // 指定标准输出描述符1为管道写指针 close(fd[1]); // 关闭原始管道写指针
execl(process1, process1, 0); // 用程序father覆盖当前程序
printf(\ // execl()执行失败 } else { close(fd[1]); // 关闭管道输出描述符 close(STD_INPUT); // 关闭标准输入描述符0 dup(fd[0]); // 指定标准输入描述符0为管道读指针 close(fd[0]); // 关闭原始管道读指针 execl(process2,process2,0); // 用程序child覆盖当前程序 printf(\ // execl()执行失败 } exit(2); // 程序结束
}
步骤2:编制“管道写”程序father.c作为父进程的一部分工作。其内容如下:
单击红帽子,在“GNOME帮助”菜单中单击“附件”-“文本编辑器”命令,在文本编辑中键入程序并保存为father.c。
清单4-6 father.c
main() {
static char string[] = “Parent is using pipe write.” ; int len;
len = sizeof(string) ; write(l, string, len) ; /* 将string中的内容写入管道中 */ printf(“parent, parent, parent \\n \\n \\n” ) ; exit(0) ; }
步骤3:编制“管道读”程序child.c作为子进程的一部分工作。其内容如下:
单击红帽子,在“GNOME帮助”菜单中单击“附件”-“文本编辑器”命令,在文本编辑中键入程序并保存为child.c。
清单4-7 child.c
软件c122郭嵘峥 125448
main() {
char output[30] ;
read (0, output, 30) ; /* 从管道中读数据并存入output中 */ printf(“%s \\n child, child. \\n” , output) ; return(0) ; }
步骤4:编译。
cc –o child child.c cc –o father father.c cc –o pipeline pipeline.c 步骤5:运行。
./pipeline 若运行不成功,则应该用文本编辑器对源程序进行修改调试。
2.4 Linux重定向和管道
(实验估计时间:90分钟)
? ? ? ? ?
背景知识 实验目的
工具/准备工作 实验内容与步骤 可选练习
背景知识
在本实验中,我们将使用高级Linux命令来完成重定向和管道。每一个Linux命令都有一个源作为标准输入,一个目的作为标准输出。命令的输入通常来自键盘 (尽管它也可以来自文件) 。命令通常输出到监视器或者屏幕上。Linux计算环境使用重定向可以控制命令的I/O。当试图把命令的输出保存到一个文件,以供以后查看的时候是很有用的。通过管道,可以取得一个命令的输出,把它作为另一个命令的进一步处理的输入。
有几个元字符可用于输入/输出重定向符号:输出重定向使用右尖括号 (>,又称大于号) ;输入重定向使用左尖括号 (<,又称小于号) ;出错输出重定向使用右尖括号之前有一个数字2 (如2>) 。本实验重点在输出重定向。
重定向命令的格式是:
Command Redirection-Symbol File (text file or device file)
标准输出比标准输入或标准出错更经常被重定向。许多命令,如ls、cat、head和tail产生标准输出到屏幕上,常常会希望把这个输出重定向到一个文件中,以便将来查看、处理或者打印。通过替换文件名,可以截获命令的输出,而不是让它到达默认的监视器上。
最强大的元字符之一是管道符号 (|) 。管道取得一个命令的标准输出,把它作为标准输入传递给下一个命令 (通常为more命令、lp (行式打印机) 命令或者一个文件处理命令,如grep或sort) 。必须在管道的每边都有一个命令,命令和管道之间的空格是可选的。
管道命令的格式是: command | command 实验目的
通过重定向和管道操作:
软件c122郭嵘峥 125448
1) 熟悉输入/输出 (I/O) 重定向; 2) 把标准输出重定向创建一个文件; 3) 防止使用重定向的时候覆盖文件; 4) 把输出追加到一个现有的文件中;
5) 把一个命令的输出导入到另一个命令中。 工具/准备工作
在开始本实验之前,请回顾教科书的相关内容。 您需要做以下准备:
1) 由指导老师分配的登录用户名 (如user2) 和口令。
2) 一台运行Red Hat Linux操作系统,带有GNOME的计算机。 实验内容与步骤
1. 使用重定向标准输出符号 2. 使用管道符号
在本实验中将会用到下列命令: pwd: 显示当前的工作路径。 cd: 改变目录路径。 ls: 显示指定目录的内容。 more: 分页显示文件的内容。这是用于显示文本文件的首选方法。 head: 截取显示文件的开头部分 (默认为开头10行) 。 tail: 截取显示文件的结尾部分 (默认为最后10行) 。 cal: 有关日历的命令。 set: shell特性的设置。 echo: 显示变量的值。 ps: 显示当前进程。 data: 显示或设置系统日期和时间。 grep: 查找文件中有无指定的关键字。
提示:如果对命令的格式不清楚,可以用man命令请求帮助,即: man more
步骤1:开机,登录进入GNOME。
在GNOME登录框中填写指导老师分配的用户名和口令并登录。 步骤2:访问命令行。
单击红帽子,在“GNOME帮助”菜单中单击“系统工具”-“终端”命令,打开终端窗口。
1. 使用重定向标准输出符号
步骤3:重定向标准输出,创建一个文件。
右尖括号或称大于符号 (>) 把命令的输出发送到一个文件中:使用单个右尖括号,当指定文件名不存在的时候,将创建一个新文件;如果文件名存在,它将被覆盖。(注意:命令、重定向符号和文件名之间的空格是可选的) 。
相关推荐: