操作系统实验报告Word格式文档下载.docx
- 文档编号:22137190
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:40
- 大小:560.25KB
操作系统实验报告Word格式文档下载.docx
《操作系统实验报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告Word格式文档下载.docx(40页珍藏版)》请在冰豆网上搜索。
如果不输入outputfilename.out,默认的输出文件是a.out。
3.最后一步是运行程序,方法如下:
./outputfilename.out
4、实验结果
图1-1vi编辑器操作
图1-2c程序运行结果
心得体会:
通过对此节课程的学校,对linux有了一个初步的了解,学习了一些简单的终端命令,掌握vi编辑器的使用,对以后的学习打下了一点基础。
二、进程管理(上)
第8周星期二3-4节
(1)加深对进程概念的理解,明确进程和程序的区别。
(2)进一步认识并发执行的实质。
(1)首先分析该段程序输出结果,然后再输入该段代码编译并运行,看看结果和自己的分析有没有不同,如果有不同,分析其原因。
#include<
stdio.h>
intmain(void)
{
inti;
i=fork();
printf("
i=%d\n"
i);
return0;
}
(2)进程的创建
编写一段源程序,使系统调用fork()创建两个子进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示一个字符:
父进程显示字符“a”;
子进程分别显示字符“b”和字符“c”。
试观察纪录屏幕上的显示结果,并分析原因。
(3)进程的控制
修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕出现的现象,并分析原因。
如果在程序中使用调用lockf()来给每一个子进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。
3、实验步骤
一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。
然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。
相当于克隆了一个自己。
(1)使用vi编辑器编辑代码,运行得到如下结果
图2-1代码运行结果
查阅资料知,在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。
在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。
由此解释了图中为何得到两个返回值。
(2)进程创建
编写源代码如下:
#include<
main()
intp1,p2;
if(p1=fork())/*子进程创建成功*/
putchar('
b'
);
else
{
if(p2=fork())/*子进程创建成功*/
putchar('
c'
elseputchar('
a'
/*父进程执行*/
}
使用vi编辑之后,运行得到如下结果:
图2-2创建进程
分析:
从进程执行并发来看,输出abc的排列都是有可能的。
原因:
fork()创建进程所需的时间虽然可能多于输出一个字符的时间,但各个进程的时间片的获得却不是一定是顺序的,所以输出abc的排列都是有可能的。
创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。
图2-3进程的控制
4、思考
系统是怎样创建进程的?
核心为系统调用fork完成下列操作:
(1)为新进程在进程表中分配一个空项。
(2)为子进程赋一个唯一的进程标识号(PID)。
(3)做一个父进程上下文的逻辑副本。
由于进程的某些部分,如正文区,可能被几个进程所共享,所以核心有时只要增加某个区的引用数即可,而不是真的将该区拷贝到一个新的内存物理区。
(4)增加与该进程相关联的文件表和索引节点表的引用数。
(5)对父进程返回子进程的进程号,对子进程返回零。
通过此次课程的学习,初步掌握了系统进程的机制,对操作系统的知识有了更深一步的理解。
三、进程管理(下)
第9周星期二3-4节
(3)分析进程竞争资源现象,学习解决进程互斥的方法。
(4)了解Linux系统中进程通信的基本原理。
2、实验预备内容
(1)阅读Linux中fork,signal,lockf等系统调用的功能和用法。
(2)了解什么是管道,了解进程间通信的常用方法。
3、实验内容
(1)编写一段程序,使其现实进程的软中断通信。
要求:
使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按DEL键);
当捕捉到中断信号后,父进程用系统调用Kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:
ChildProcessllisKilledbyParent!
ChildProcessl2isKilledbyParent!
父进程等待两个子进程终止后,输出如下的信息后终止
ParentProcessisKilled!
(2)编制一段程序,实现进程的管理通信。
使用系统调用pipe()建立一条管道线;
两个子进程P1和P2分别向管道中写一句话:
Child1issendingamessage!
Child2issendingamessage!
而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。
要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。
4、实验步骤
(1)进程的软中断通信
使用vi编辑器,编写如下代码:
#include
<
stdlib.h>
string.h>
signal.h>
unistd.h>
sys/types.h>
int
wait_mark;
/*定义等待标记,当其为1时,表示需要等待。
*/
void
start()
wait_mark=0;
static
waiting()
while(wait_mark==1);
/*循环创建进程至成功为止*/
stat1=0,stat2=0;
pid1,pid2;
while((pid1=fork())==-1);
if(pid1>
0)
/*当判断为父进程时*/
printf("
chilld
process
1
is
%d\n"
pid1);
while((pid2=fork())==-1);
if(pid2>
0)
child
2
pid2);
please
press
'
delete'
\n"
wait_mark=1;
/*将等待标记置0至到信号激会start*/
if(signal(SIGINT,start))
;
else
/*这个判断可以使在没有接受到ctrl+c中断的情况下,自倒数5秒后,发出中断信号,以使程序正常运行。
alarm(5);
signal(SIGALRM,start);
/*SIGALRM是在alarm()后激会的软中断信号,如果5秒后没按下ctrl+c则自行激活这个信号*/
waiting();
/*在wait_mark置0前,不可往下执行*/
/*下面为往两个子进程发送中断信号*/
kill(pid1,16);
kill(pid2,17);
wait(0);
Parent
killed!
exit(0);
else
signal(SIGINT,
SIG_IGN);
//signal(SIGQUIT,
/*此处用于实验两个参数之间的差别*/
/*等待标记置1,至到收到信号*/
signal(17,start);
/*当子进程收到父进程经
KILL发送的信号时,等待标记置0*/
Child
killed
by
parent!
/*此子进程的操作与上一个一致*/
//signal(SIGINT,
signal(SIGQUIT,
signal(16,start);
程序运行之后得到如下结果:
图3-1进程的软中断通信
该程序可以实现通过接ctrl+c传入中断信息进行I测试,不过未能通过按下“delete”来实现。
SIGINT,SIGQUIT都是中止信号,只是所属定义的按键(或事件)不同而已.SIG_IGN是忽略此信号,也就是此信号不产生我们所需要的动作.还有SID-DFL是系统默认的信号操作.此实验实现了通过父进程发出的软中断传给子进程从而对其进行终止操作。
子进程1使用了signal(SIGQUIT,SIG_IGN);
所以在按下ctrl+c退出时,也一并给终止了,所以未能显示kill信息
子进程2使用了signal(SIGINT,SIG_IGN);
在按下ctrl+c时,进程2未被中终,所以能接收到父进程传来的17号中断信息,从而正常终止,显示kill信息。
(2)进程的管理通信
#define
MSGSIZE
30
char
*msg1
=
"
sending
a
message!
*msg2
waiting(int
flag)
while(flag
==
0);
main(void)
inbuf[MSGSIZE];
p[2];
pid_t
pid1;
/*定义子进程的变量*/
pid2;
/*创建管道*/
if(pipe(p)==1)
perror("
pipe
call"
exit
(1);
pid1=fork();
/*这里定义第一个子进程*/
if(pid1<
Error.NO.1
fock
call
fail\n"
if(pid1
/*当第一个子进程运行时*/
This
the
NO.1
process\n"
/*对子进程关闭读端*/
close(p[0]);
writing
msg..\n"
write(p[1],msg1,MSGSIZE);
/*向管道写信息*/
finish
writing..\n"
pid2=fork();
/*第二个子进程在判断为父进程后再创建.这样可以避免了在第一进程中再次创建下一级的一个子进程*/
if(pid2<
Error.NO.2
if(pid2
/*当第二个子进程运行时*/
NO.2
write(p[1],msg2,MSGSIZE);
parent
/*对父进程关闭写端*/
close(p[1]);
read(p[0],inbuf,MSGSIZE);
%s\n"
inbuf);
Fork
end.\n\n"
程序运行得如下结果:
图3-2进程的管理通信
整个程式的运行顺序为:
子进程1建立->
子进程1向管道写信息->
子进程2建立->
子进程2向管道写信息->
父进程接收子进程1传递的信息->
父进程接收子进徎传递的信息->结束。
不过可能地因为系统调度的原因。
有时会出现小部分的顺序先后差异,如父进程先接收子进程1的信息后,子进程2再各管道写入信息,不过总体处理顺序不变,父进程依次向1,2子进程读取信息并输出。
通过查询资料得,fork()不仅创建出与父进程代码相同的子进程,而且父进程在fork执行点的所有上下文场景也被自动复制到子进程中,包括:
全局和局部变量、打开的文件句柄、共享内存、消息等同步对象。
此次学习,不仅对上次课程有一个回顾,而且更多得了解到系统一些函数的使用方法和其作用,更好的理解了系统进程的调度机制。
四、shell程序设计
第10周星期二3-4节
(1)了解Linux的Bash基本知识
(2)了解什么是shell程序
(3)学会编写简单shell程序的一般方法
2、实验内容
(1)查看本Linux有哪些shell?
(2)查看env命令的输出,并理解该命令输出的环境变量的含义
(3)通过编辑/etc/issue和/etc/motd这两个文件来设置进系统的提示和登录系统以后的欢迎信息。
(提示:
修改之后用“init3”这个命令可以观察到效果)。
(4) 用户可以用任何编辑程序来编写shell程序。
因为shell程序是解释执行的,所以不需要编译装配成目标程序,按照shell编程的惯例,以bash为例,程序的第一行一般为“#!
/bin/bash”,其中#表示该行是注释,叹号“!
”告诉shell运行叹号之后的命令并用文件的其余部分作为输入,也就是运行/bin/bash并让/bin/bash去执行shell程序的内容。
分析如下的shell程序运行结果,然后把代码保存为文件test.sh,设置该文件的执行权限,并运行看结果和自己的分析有什么不同。
#!
/bin/sh
salutation=“Hello”
echo“Theprogram$0isnowrunning”
echo“Thesecondparameterwas$2”
echo“Thefirstparameterwas$1”
echo“Theparameterlistwas$*”
echo“Theuser’shomedirectoryis$HOME”
echo“Pleaseenteranewgreeting”
readsalutation
echo$salutation
echo“Thescriptisnowcomplete”
exit0
3、实验结果
使用vi编辑器编写设置进系统的提示和登录系统以后的欢迎信息。
motd文件、issue文件如下:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 实验 报告