操作系统实验报告
一、预备实验
(1)熟悉操作系统开发环境
实验目的
1.了解 Ubuntu 系统基本操作方法,学会独立使用该系统。
2.熟悉 Ubuntu 下如何编辑、编译和运行一个 C 语言程序。
3.学会利用 gcc、gdb 编译、调试 C 程序。
实验内容
1.举例列出常用的 shell 命令使用方法
目录操作
mkdir abc 创建一个目录 abc
cd abc 将工作目录改变到 abc
cd 改变当前目录到主目录
ls 列出当前目录的内容
ls -l 输出当前目录内容的长列表,每个目录或文件占一行
pwd 显示当前目录的全路径
文件显示实用程序
cat mx.c 显示 mx.c 文件内容
more mx.c 分屏显示 mx.c 内容
tail mx.c 显示文件后几行
cat file1 file2 连接 file1 和 file2
head filename 显示文件 filename 的开始 10 行
wc filename 统计文件 filename 中的行数、单词数和字符数
od 文件 查看非文本文件
文件管理实用程序
cp file1 file2 将文件 1 复制到文件 2
mv file1 file2 将文件重命名为 file2
rm filename 删除文件 filename
rm -i filename 请求用户确认删除
数据操作实用程序
tty 显示当前终端的路径和文件名
who 显示当前登录用户的列表
sort filename 显示文件 filename 中的行的排序结果
spell filename 检查文件 filename 中的拼写错误
其他实用程序
date 输出系统日期和时间
cal 显示本月的日历。cal 2002 显示 2002 年的日历
clear 清除终端屏幕
history 显示你以前执行过的命令的列表
man 显示实用程序的有用信息,并提供该实用程序的基本用法
echo 读取参数并把它写到输出
2.通过实例总结上机调试 C 语言程序的过程及此次上机的感想。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aaFPvzCO-1636375811113)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100041330.png)]
总结运行过程如下:先在vim编辑器里编写hello.c代码,然后再通过gcc编译器编译,编译先生成hello.i文件,最后通过gcc -o hello.out链接生成可运行文件,最后输出。也可以直接一行命令gcc -o hello.out hello.c编译生成可运行文件。
a. 预处理,把预处理命令扫描处理完毕;
b. 编译,把预处理后的结果编译成汇编或者目标模块;
c. 汇编,把编译出来的结果汇编成具体 CPU 上的目标代码模块;
d. 连接,把多个目标代码模块连接生成一个大的目标模块;
实验感想
通过本次实验,复习了Linux系统的基本命令行操作,除此之外,还复习了c语言代码的编译过程,收获颇丰。
(2)shell脚本
实验目的
1、了解和熟悉创建并使用脚本的步骤。
2、熟悉 bash 的控制结构。
3、学会简单的 shell 编程。
实验内容
1.列出调试通过程序的清单,并加注释。
1、 创建一个简单的列目录和日期的 shell 脚本并运行之。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x85nAcOk-1636375811117)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100729010.png)]
2、 用 Shell 语言编制一 Shell 程序,该程序在用户输入年、月之后,自动打印数出该年该月的日历。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gmHM0XBO-1636375811119)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100742934.png)]
3、 编程提示用户输入两个单词,并将其读入,然后比较这两个单词,如果两个单词相同则显示“Match”,并显示“End of program”,如果不同则显示“End of program”。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pICMRQld-1636375811121)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100652261.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xI2kTrpt-1636375811122)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100658759.png)]
4、修改上述程序,编程提示用户输入两个单词,并将其读入,然后比较这两个单词,如果两个单词相同显示“Match”,不同则显示“Not match”,最后显示“End of program”。
<编程提示>请使用 if…then…else 控制结构。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zAaJ5haw-1636375811124)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100758930.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HUn2uHTa-1636375811125)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100805426.png)]
5、编程使用 case 结构创建一个简单的菜单,屏幕显示菜单:
a. Current date and time
b. User currently logged in
c. Name of the working directory
d. Contents of the working directory
Enter a,b,c or d:
根据用户输入选项做相应操作。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QIe48pkd-1636375811126)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100820889.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h1vnqptf-1636375811127)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100827614.png)]
6、修改上题,使用户可以连续选择直到想退出时才退出。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wqTl4wYK-1636375811127)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100843068.png)]
7、编程使用 select 结构生成一个菜单如下:
1)apple 3)blueberry 5)orange 7)STOP
- banana 4)kiwi 6)watermelon
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5dJ7fMaq-1636375811128)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100859039.png)]
2.回答思考题
1、 什么选项通知 rm、cp 和 mv 在删除或覆盖文件前得到用户的确认?
答:-i选项
2、 如何确认自己在主目录中?然后再主目录中创建一个名为Dannty的目录,再进入到Danny目录,并确认你的位置?
答:
Mkdir Dannty
Cd Dannty
Pwd
3、 命令 echo$PATH 的输出是什么?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QsNo33Ab-1636375811129)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100914495.png)]
4、下列命令的运行结果是什么?
who | grep $USER
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m0n0Jodk-1636375811130)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100934827.png)]
grep $HOME file1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N9r1C4gc-1636375811131)(C:\Users\pj\AppData\Roaming\Typora\typora-user-images\image-20210109100948448.png)]
实验感想
**问题:**在编写第4题时,不知道shell语言中的循环语句怎么写
**解决方法:**上网查询相关博客,了解到shell语言中的循环语句写法大致与c语言相似,只是在某些小细节有所差别。
**感想:**通过本次实验,学会了如何编写shell脚本文件。在平时做项目中,我们经常会接触到shell脚本文件,此次系统的学习了如何编写shell脚本文件,极大地便于我们日后做项目的需要。
二、进程实验
(1)进程控制
实验目的
1、掌握进程的概念,明确进程和程序的区别。
2、认识和了解并发执行的实质。
3、分析进程争用资源的现象,学习解决进程互斥的方法。
实验内容
1.进程的创建
#include<stdio.h>
main()
{
int p1,p2;
while((p1=fork())==-1);
if(p1==0)
putchar('b');
else
{
while((p2=fork())==-1);
if(p2==0)
putchar('c');
else
putchar('a');
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MXx3silE-1636375811131)(C:\Users\pj\Desktop\操作系统\OSexp2\exp2_1_1.png)]
2、 修改已编写的程序,将每个进程的输出由单个字符改为一句话,再观察程序执行时屏幕上出现的现象,并分析其原因。
#include <stdio.h>
main()
{
int p1,p2,i;
while((p1=fork())==-1);
if(p1==0)
for(i=0;i<500;i++)
printf("child%d\n",i);
else
{
while((p2=fork())==-1);
if(p2==0)
for(i=0;i<500;i++)
printf("son%d\n",i);
else
for(i=0;i<500;i++)
printf("daughter%d\n",i);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-566djf9n-1636375811132)(C:\Users\pj\Desktop\操作系统\OSexp2\exp2_1_2.png)]
3、编写程序创建进程树如图 1 和图 2 所示,在每个进程中显示当前进程识别码和父进程识别码。
#include <stdio.h>
#include <unistd.h>
int main()
{
int p1,p2,p3,p4;
while((p1=fork())==-1);
if(p1>0)
{
printf("process a(its id=%d,its father pid is %d\n",getpid(),getppid());
}
else
{
printf("process b(its id=%d,its father pid is %d\n",getpid(),getppid());
while((p2=fork())==-1);
if(p2==0)
{
printf("process c(its id=%d,its father pid is %d\n",getpid(),getppid());
while((p3=fork())==-1);
if(p3==0)
printf("process d(its id=%d,its father pid is %d\n",getpid(),getppid());
}
}
return 0;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K1aPWIJR-1636375811133)(C:\Users\pj\Desktop\操作系统\OSexp2\exp2_1_3.png)]
实验感想
通过本次上机实验,学习了进程的创建方法,掌握了进程的概念,明确了进程与程序的区别。对并发与并行的认识进一步加深了。
(2)进程间通信
实验目的
1、了解什么是信号。
2、熟悉 LINUX 系统中进程之间软中断通信的基本原理。
实验内容
1、编写一段程序,使用系统调用 fork( )创建两个子进程,再用系统调用 signal( )让父进程捕捉键盘上来的中断信号(即按 ctrl+c 键),当捕捉到中断信号后,父进程用系统调用 kill( )向两个子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止:
Child process 1 is killed by parent!
Child process 2 is killed by parent!
父进程等待两个子进程终止后,输出以下信息后终止:
Parent process is killed!
# include<stdio.h>
# include<signal.h>
# include<unistd.h>
int wait_mark=0;
void waiting()
{
while(wait_mark!=0);
}
void stop()
{
wait_mark=0;
}
int main()
{
int p1, p2;
signal(SIGINT,stop);
while((p1=fork())==-1);
if(p1>0)
{
while((p2=fork())==-1);
if(p2>0)
{
wait_mark=1;
waiting(0);
kill(p1,10);
kill(p2,12);
wait();
wait();
printf("parent process is killed!\n");
exit(0);
}
else
{
wait_mark=1;
signal(12,stop);
waiting();
lockf(1,1,0);
printf("child process 2 is killed by parent!\n");
lockf(1,0,0);
exit(0);
}
}
else
{
wait_mark=1;
signal(10,stop);
waiting();
lockf(1,1,0);
printf("child process 1 is killed by parent!\n");
lockf(1,0,0);
exit(0);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lFLzuZ0V-1636375811133)(C:\Users\pj\Desktop\操作系统\OSexp2\exp2_2_1.png)]
2、修改上面的程序,增加语句 signal(SIGINT,SIG_IGN)和语句 signal(SIGQUIT,SIG_IGN),再观察程序执行时屏幕上出现的现象,并分析其原因。
# include<stdio.h>
# include<signal.h>
# include<unistd.h>
int main()
{
int pid1, pid2;
int EndFlag=0;
int SIGUSER1=16;
void IntDelete()
{
kill(pid1,10);
kill(pid2,12);
EndFlag=1;
}
void Int1()
{
printf("child process 1 is killed by parent !\n");
exit(0);
}
void Int2()
{
printf("child process 2 is killed by parent !\n");
exit(0);
}
int exitcode;
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
while((pid1=fork())==-1);
if(pid1==0)
{
signal(SIGUSER1,Int1);
signal(SIGQUIT,SIG_IGN);
pause();
exit(0);
}
else
{
while((pid2=fork())==-1);
if(pid2==0)
{
signal(SIGUSER1,Int1);
signal(SIGQUIT,SIG_IGN);
pause();
exit(0);
}
else
{
signal(SIGINT,IntDelete);
waitpid(-1,&exitcode,0);
printf("parent process is killed \n");
exit(0);
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GLdX6Ta9-1636375811134)(C:\Users\pj\Desktop\操作系统\OSexp2\exp2_2_2.png)]
实验感想
通过本次实验,我了解什么是信号,并且熟悉 了LINUX 系统中进程之间软中断通信的基本原理。
(3)进程间的管道通信实验
实验目的
1、了解什么是管道
2、熟悉 UNIX/LINUX 支持的管道通信方式
实验内容
1、编制一段程序,实现进程的管道通信。使用 pipe()建立一条管道线。两个子进程 p1 和p2 分别向管道各写一句话:
Child 1 is sending message!
Child 2 is sending message!
而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。
# include<unistd.h>
# include<signal.h>
# include<stdio.h>
int pid1,pid2;
int main()
{
int fd[2];
char OutPipe[100],InPipe[100];
pipe(fd);
while((pid1=fork())== -1);
if(pid1==0)
{
lockf(fd[1],1,0);
sprintf(OutPipe," child 1 process is sending message!");
write(fd[1],OutPipe,50);
sleep(5);
lockf(fd[1],0,0);
exit(0);
}
else
{
while((pid2=fork())== -1);
if(pid2==0)
{
lockf(fd[1],1,0);
sprintf(OutPipe,"child 2 process is sending message!");
write(fd[1],OutPipe,50);
sleep(5);
lockf(fd[1],0,0);
exit(0);
}
else
{
wait(0);
文章评论