学 生 实 验 报 告
姓名: 黄维津 年级专业班级 计科141班 学号 201415210137 成绩
课程名称
操作系统
实验名称
实验1 操作系统界面
【实验目的、要求】
1. 熟悉Linux字符操作界面;
2. 熟悉常用的Shell命令;
3. 熟悉Linux文本编辑方法;
4. 掌握利用GCC编译器在Linux环境下编译C程序的能力
【实验内容】
1. Linux字符操作界面;
2. Shell操作命令;
3. VIM编辑器的使用方法;
4. Linux下的C程序开发。
【实验环境】(含主要设计设备、器材、软件等)
计算机 C语言编程软件 redhat操作系统 VM虚拟机
【实验步骤、过程】(含原理图、流程图、关键代码,或实验过程中的记录、数据等)
同时按住“Ctrl+Alt+Shift+F2”键进入字符操作界面;
熟悉常用的Shell操作命令
(1)查看系统分区情况:fdisk -l
(2)查看当前运行级别:runlevel
可知,当前运行级别为:5
(3)将当前运行级别改变为3:init 3
运行后的结果如下图:
输入命令runlevel查看当前运行级别可知为3
(4)新建文件:touch 文件名
这里创建了一个文件名为test.txt的文件
(5)删除文件:rm 要删除的文件名
这里我删除了刚新建的test.txt文件,输入ls命令已查看不到test.txt文件了,证明已删除成功。
(6)查看文件权限:ls -l
可知hello.c文件的权限是644
(7)更改文件权限:chmod 文件权限 文件名
这里将hello.c文件的权限更改为755,即rwxr-xr-x
VIM编辑器的使用方法
(1)一般模式:以vi打开一个文件就直接进入一般模式了(这是默认的模式)。
(2)编辑模式:在一般模式中可以进行删除、复制、粘贴等的操作,但是却无法编辑文件的内容,只有当到你按下【i, I, o, O, a, A, r, R】等任何一个字母之后才会进入编辑模式。按下【Esc】即可退出编辑模式
(3)命令行模式:输入【 : / ? 】三个中的任何一个,就可以将光标移动到最底下那一行。
在命令行模式下,可选用以下指令离开vi:
:q! 退出,不保存;
:wq 保存退出;
Linux下的C程序开发
(1)使用touch命令创建c文件hello.c;
(2)使用vi hello.c命令编辑c文件:
#include <stdio.h>
int main(){
printf(“hello,word”);
return 0;
}
(3)按esc键 [进入命令模式]
(4)输入:“:wq!”保存退出;
(5)编译程序:gcc -o hello hello.c
(6)运行程序:./hello
(7)运行结果:输出hello,word
2016年 11月 20日
【实验结果或总结】(对实验结果进行相应分析,或总结实验的心得体会,并提出实验的改进意见)
在实验的过程中,我用的是VM虚拟机和redhat操作系统(linux系统中的一种),学会了如何在虚拟机上安装并运行linux操作系统,也熟悉了Linux字符操作界面和常用的shell命令。虽然我一开始从图形操作界面转到命令行操作界面多少有些不适应,但随着对命令行的熟悉应用,发现也没那么难,只是命令行太多了会记不住。与此同时,第一次在linux系统下编写c程序,感觉用vi比较麻烦,因为有错了不能调试,只是提示错误。不过此次实验要求掌握编写并运行一个简单的c程序,我就直接输出一句话就好了,所以不需要怎么调试了,直接用gcc编译并运行。在这实验的过程中,加深了对一些术语的理解,也让我学到了新的知识。
要说到实验的改进意见,我想最大要改进的地方就是要提高虚拟机运行的流畅度,不能在使用虚拟机中的操作系统时出现运行卡顿等的情况,以保住实验的流畅进行。
指导教师签名:
20 年 月 日
【备注】
学 生 实 验 报 告
姓名: 黄维津 年级专业班级 计科141 学号 201415210137 成绩
课程名称
操作系统
实验名称
实验2 进程管理
【实验目的、要求】
1.熟悉进程与程序的区别,加深对进程概念的理解;
2.了解并发进程的执行过程;
3.掌握解决进程互斥使用资源的方法。
【实验内容】
1. 编写一段程序,实现进程的管理;
2. 编写一段程序实现进程的通信。
【实验环境】(含主要设计设备、器材、软件等)
信息楼505机房
Linux环境
【实验步骤、过程】(含原理图、流程图、关键代码,或实验过程中的记录、数据等)
编写一个程序,创建两个子进程,然后分别在父、子进程中显示它们的进程号,以及对于的父进程号
(1)思路:使用系统调用fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“A”,子进程分别显示字符“b”和“c”。
(2)程序关键代码
#include<stdio.h>
main(){
int p1,p2;
if(p1=fork())/*子进程创建成功,如果失败fork函数会返回一个负值*/
putchar('b');
else{
if(p2=fork())/*子进程创建成功,如果失败fork函数会返回一个负值*/
putchar('c');
else putchar('A');/*父进程执行*/
}
}
(3)运行结果:Abc任意的排序
(4)结果分析:
从进程执行并发来看,输出Abc的排列都是有可能的。fork()函数创建进程所需的时间虽然可能多于输出一个字符的时间,但各个进程的时间片的获得却不一定是顺序的,所以输出Abc的排列都是有可能的。
写一个程序,实现父子进程之间的通信
用管道实现:
pipe_named_write.c
// 向管道文件写信息
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main(){
FILE * out_file;
int count = 1;
char buf[80];
out_file = fopen(“mypipe”,”w”);
if (out_file==NULL){
printf(“Error opening pipe”);
exit(1);
}
sprintf(buf, ”this is the test data for the named pipe example \n”);
fwrite(buf,1,88,out_file);
fclose(out_file);
}
pipe_named_read.c
// 从管道文件读信息
int main(){
FILE *in_file;
int count = 1;
char buf[80];
in_file = fopen(“mypipe”, “r”);
if (in_file == NULL){
printf(“Error in fopen. \n”);
exit(1);
}
while ( (count = fread(buf,1,80,in_file))>0)
printf(“received from pipe: %s \n”,buf);
fclose()in_file;
}
使用FIFO实现进程间的通信。用mkfifo函数创建管道文件my_fifo,然后从Data.txt文件中读取数据,并写入管道文件my_fifo中;在从管道文件my_fifo中读取数据,写入DataFromFIFO.txt文件中。整个过程用两个C程序来实现:fifowrite.c文件实现管道文件的创建,以及将Data.txt文件中的数据读入管道文件中;fiforead.c文件实现从管道文件中读取数据,并写入DataFromFIFO.txt文件中。
fifowrite.c的源代码如下:
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
int main()
{
const char *fifo_name = "/home/c/my_fifo";
int pipe_fd = -1;
int data_fd = -1;
int res = 0;
const int open_mode = O_WRONLY;
int bytes_sent = 0;
char buffer[PIPE_BUF + 1];
if(access(fifo_name, F_OK) == -1)
{
// 管道文件不存在
// 创建命名管道
res = mkfifo(fifo_name, 0777);
if(res != 0)
{
fprintf(stderr, "Could not create fifo %s\n", fifo_name);
exit(EXIT_FAILURE);
}
}
printf("Process %d opening FIFO O_WRONLY\n", getpid());
// 以只写阻塞方式打开FIFO文件,以只读方式打开数据文件
pipe_fd = open(fifo_name, open_mode);
data_fd = open("Data.txt", O_RDONLY);
printf("Process %d result %d\n", getpid(), pipe_fd);
if(pipe_fd != -1)
{
int bytes_read = 0;
// 向数据文件读取数据
bytes_read = read(data_fd, buffer, PIPE_BUF);
buffer[bytes_read] = '\0';
while(bytes_read > 0)
{
// 向FIFO文件写数据
res = write(pipe_fd, buffer, bytes_read);
if(res == -1)
{
fprintf(stderr, "Write error on pipe\n");
exit(EXIT_FAILURE);
}
// 累加写的字节数,并继续读取数据
bytes_sent += res;
bytes_read = read(data_fd, buffer, PIPE_BUF);
buffer[bytes_read] = '\0';
}
close(pipe_fd);
close(data_fd);
}
else
exit(EXIT_FAILURE);
printf("Process %d finished\n", getpid());
exit(EXIT_SUCCESS);
}
源文件fiforead.c的代码如下:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <string.h>
int main()
{
const char *fifo_name = "/home/c/my_fifo";
int pipe_fd = -1;
int data_fd = -1;
int res = 0;
int open_mode = O_RDONLY;
char buffer[PIPE_BUF + 1];
int bytes_read = 0;
int bytes_write = 0;
// 清空缓冲数组
memset(buffer, '\0', sizeof(buffer));
printf("Process %d opening FIFO O_RDONLY\n", getpid());
// 以只读阻塞方式打开管道文件,注意与fifowrite.c文件中的FIFO同名
pipe_fd = open(fifo_name, open_mode);
// 以只写方式创建保存数据的文件
data_fd = open("DataFormFIFO.txt", O_WRONLY|O_CREAT, 0644);
printf("Process %d result %d\n",getpid(), pipe_fd);
if(pipe_fd != -1)
{
do
{
// 读取FIFO中的数据,并把它保存在文件DataFormFIFO.txt文件中
res = read(pipe_fd, buffer, PIPE_BUF);
bytes_write = write(data_fd, buffer, res);
bytes_read += res;
}while(res > 0);
close(pipe_fd);
close(data_fd);
}
else
exit(EXIT_FAILURE);
printf("Process %d finished, %d bytes read\n", getpid(), bytes_read);
exit(EXIT_SUCCESS);
}
运行结果如下:
2016 年 11 月 26 日
【实验结果或总结】(对实验结果进行相应分析,或总结实验的心得体会,并提出实验的改进意见)
在查询了资料后逐渐懂得怎么下手完成这个实验,在实验过程中逐渐理解了进程的概念,并进一步了解了进程的管理机制,同时也明白了什么是管道通信,怎样加锁和解锁,对课本上的知识理解得更加深入了。同时也让我认识到自己的不足,操作系统的有些知识,我知道的还不多,没有掌握好,还需要多多学学,不断提升自己的能力。
指导教师签名:
年 月 日
【备注】
学 生 实 验 报 告
姓名: 黄维津 年级专业班级 计科141 学号 201415210137 成绩
课程名称
操作系统
实验名称
实验3 存储管理
【实验目的、要求】
1. 了解虚拟存储管理技术的原理与特点;
2. 掌握请求页式存储管理的页面设置算法。
【实验内容】
1. 编写一个程序模拟存储管理过程。
【实验环境】(含主要设计设备、器材、软件等)
计算机 C语言编程软件
【实验步骤、过程】(含原理图、流程图、关键代码,或实验过程中的记录、数据等)
页式虚拟存储管理程序模拟
(1)设计思路
根据模拟的页式管理设计,在页式存储管理中有三种最基本的页面调度算法:最佳置换算法(OPT)、先进先出置换算法(FIFO)、最近最久未使用置换算法(LRU),但在三种算法中均要求在调度程序中产生的页面序列是随机产生的,而不是人为的输入,在执行时只需改变页面的大小及内存容量就可以得到不同的页面序列,另外还需要说明随机的性能和其性能可能对算法的影响,并对随机性要有一定的参数控制能力。此次实验将使用两种方法实现,分别是先进先出(FIFO)页面置换和最近最久未使用(LRU)置换。
程序流程图
输入内存分配页数
输入内存分配页数
开始
初始化第一列值
是否有请求访问页
复制前一页内容
内存是否已存在
内存是否有空页
直接插入
替换内存中将来不出现或离当前最远的页
输出全部页面变化情况
结束
Y
Y
N
N
Y
N
(3)关键代码
<FIFO算法关键代码>
function FIFO(){
PageList = [6 2 1 0 3 4 2 0 4 5 9 3 1 2 0 5 3 1 8]; // 初始化:
NumofPage = length(PageList);
NumofPosition = M;
SMatrix[NumofPosition][2] = {-1}; // 将其初始化为-1
for( i=0; i<NumofPage;i++){
pos = findPositionFIFO(SMatrix,PageList[i]);
if (pos==-1) continue; // 在SMatrix中找到页面已经存在
for (j=0;j<M;j++) {
if (SMatrix[i][2]>0) SMatrix[i][2] = SMatrix[i][2] + 1;
}
SMatrix[pos][1] = PageList[i];
if (SMatrix[pos][2] ==-1){ SMatrix[pos][2] = 1}
}
}
function pos = findPositionFIFO(SMatrix,Pageid){
NumofPosition = length(SMatrix);
lastPeriod = SMatrix[0][2];
value = SMatrix[0][1];
for (i=0; i<NumofPosition;i++){
if (SMatrix[i][1] ==-1) {
pos = i;
return;
}
elseif (SMatrix[i][1] ==Pageid){
pos = -1;
return;
}
elseif (SMatrix[i][2] > lastPeriod){
pos = i;
lastPeriod = SMatrix[i][2];
}
}
}
<LRU算法关键代码>
function LRU(){
PageList = [6 2 1 0 3 4 2 0 4 5 9 3 1 2 0 5 3 1 8]; // 初始化:
NumofPage = length(PageList);
NumofPosition = M;
SMatrix = array[NumofPosition][2]; // 将其初始化为-1
for( i=0; i<NumofPage;i++){
[pos isIn] = findPositionLRU(SMatrix,PageList[i]);
if (pos==-1) { // 在SMatrix中找到页面已经存在
SMatrix[i][2] = 1;
continue;
}
for (j=0;j<M;j++) {
if (SMatrix[i][2]>0) SMatrix[i][2] = SMatrix[i][2] + 1;
}
SMatrix[pos][1] = PageList[i];
if (SMatrix[pos][2] ==-1){ SMatrix[pos][2] = 1}
}
}
function [pos isIn] = findPositionLRU(SMatrix,Pageid){
NumofPosition = length(SMatrix);
lastPeriod = SMatrix[0][2];
value = SMatrix[0][1];
isIn = 0;
for (i=0; i<NumofPosition;i++){
if (SMatrix[i][1] ==-1) {
pos = i;
return;
}
elseif (SMatrix[i][1] ==Pageid){
pos = -1;
isIn = 1;
return;
}
elseif (SMatrix[i][2] > lastPeriod){
pos = i;
lastPeriod = SMatrix[i][2];
}
}
}
2016 年 11 月 26 日
【实验结果或总结】(对实验结果进行相应分析,或总结实验的心得体会,并提出实验的改进意见)
由于知识有限,只能大概地完成这次实验。通过完成这个实验,让我反复地琢磨着课本上的知识点,努力将其弄懂,这样才有思路来完成实验。从理论到实践可以学到很多的东西,同时也可以巩固老师在课堂上讲过的知识,也学到了很多在书本上学不到的知识。通过这次实验使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的。
指导教师签名:
20 年 月 日
【备注】
学 生 实 验 报 告
姓名: 黄维津 年级专业班级 计科141 学号 201415210137 成绩
课程名称
操作系统
实验名称
实验4 文件管理
【实验目的、要求】
1. 了解文件系统的功能和内部实现;
2. 熟悉文件系统的系统调用;
【实验内容】
使用有关文件系统的系统调用create()、open()、close()、read()和write()将file1.c和file2.c合并为file3.c;
【实验环境】(含主要设计设备、器材、软件等)
计算机 C语言编程软件
【实验步骤、过程】(含原理图、流程图、关键代码,或实验过程中的记录、数据等)
(1)了解函数
create()函数:
功能描述:创建一个文件并以只写的方式打开
函数原型:int creat(const char * pathname, mode_t mode)
参数说明:pathname:指向欲建立的文件路径字符串
mode_t mode:表示新建文件的权限
返回值:成功:返回文件描述符
失败:返回-1
open()函数:
功能描述:用于打开或创建文件,在打开或创建文件时可以指定文件的属性及用户的权限等各种参数。
函数原型:int open(const char *pathname,int flags,int perms)
参数说明:pathname:被打开的文件名(可包括路径名如"dev/ttyS0")
flags:文件打开方式
perms:被打开文件的存取权限
返回值: 成功:返回文件描述符
失败:返回-1
close()函数:
功能描述:用于关闭一个被打开的的文件
函数原型:int close(int fd)
参数说明:fd文件描述符
函数返回值:0成功,-1出错
read()函数
功能描述: 从文件读取数据
函数原型:ssize_t read(int fd, void *buf, size_t count)
参数说明:fd: 将要读取数据的文件描述词
buf:指缓冲区,即读取的数据会被放到这个缓冲区中去
count: 表示调用一次read操作,应该读多少数量的字符
返回值:返回所读取的字节数;0(读到EOF);-1(出错)
write()函数
功能描述: 向文件写入数据
函数原型:ssize_t write(int fd, void *buf, size_t count)
返回值:写入文件的字节数(成功);-1(出错)
(2)关键代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
char s1filename[20],s2filename[20],dfilename[20];
FILE *s1fp,*s2fp,*dfp;
int num=0;
/*得到第一个文件的文件名*/
printf("Please input source1 filename:\n");
gets(s1filename);
/*得到另一个文件的文件名*/
printf("Please input source2 filename:\n");
gets(s2filename);
/*得到要目标文件的文件名*/
printf("Please input destination filename:\n");
gets(dfilename);
/*输出信息合并前的文件的内容*/
if((s1fp=fopen(s1filename,"r"))==0)
{
printf("Can't open the file :%s\n",s1filename);
exit(0);
}
if((s2fp=fopen(s2filename,"r"))==0)
{
printf("Can't open the file :%s\n",s2filename);
exit(0);
}
if((dfp=fopen(dfilename,"w+"))==0)
{
printf("Can't open or create the file :%s\n",dfilename);
exit(0);
}
/*输出信息合并前文件的内容*/
printf("\nThe text of the file %s before merging :\n",s1filename);
OutputFile(s1fp);
printf("\nThe text of the file %s before merging :\n",s2filename);
OutputFile(s2fp);
fseek(s2fp,0L,SEEK_SET);
fseek(s1fp,0L,SEEK_SET);
/*信息合并*/
MergeFile(s1fp,s2fp,dfp,&num);
/*输出信息合并后文件的内容*/
printf("\nThe text of the file %s after merging :\n",dfilename);
fseek(dfp,0L,SEEK_SET);
OutputFile(dfp);
/*输出总的字符数*/
printf("\nand the file %s has %d chars\n",dfilename,num);
fclose(s1fp);
fclose(s2fp);
fclose(dfp);
getch();
//return 0;
}
OutputFile函数用于输出文件内容:
void OutputFile(FILE *fp)
{
char ch;
while((ch=fgetc(fp))!=EOF)
putchar(ch);
}
MergeFile函数用于文件信息合并:
void MergeFile(FILE *s1fp,FILE *s2fp,FILE *dfp,int *num)
{
char ch1,ch2;
/*初始化ch1和ch2为文件的首字符*/
ch1=fgetc(s1fp);
ch2=fgetc(s2fp);
/*从文件中读取字符,直到有一个文件结束*/
while((ch1!=EOF)&&(ch2!=EOF))
/*进行字符的比较*/
if(ch1<=ch2)
{
fputc(ch1,dfp);
/*字符数增加1*/
*num=*num+1;
ch1=fgetc(s1fp);
}
else
{
fputc(ch2,dfp);
/*字符数增加1*/
*num=*num+1;
ch2=fgetc(s2fp);
}
/*如果文件s1fp结束,则将文件s2fp的剩余内容写入到文件dfp*/
if(ch1==EOF)
while((ch2=fgetc(s2fp))!=EOF)
{
fputc(ch2,dfp);
/*字符数增加1*/
*num=*num+1;
}
/*如果文件s2fp结束,则将文件s1fp的剩余内容写入到文件dfp*/
else
while((ch1=fgetc(s1fp))!=EOF)
{
fputc(ch1,dfp);
/*字符数增加1*/
*num=*num+1;
}
}
2016 年 11 月 26 日
【实验结果或总结】(对实验结果进行相应分析,或总结实验的心得体会,并提出实验的改进意见)
这个实验主要是运用了之前学过的C语言来实现编写,熟悉了文件系统的系统调用过程。通过上机实践,对于C的语法知识有了感性的认识,加深了对它的理解,在理解的基础上自然而然地掌握c语言的语法规定。通过解决这些问题,可以逐步提高自己对c语言的理解和程序开发能力。
指导教师签名:
20 年 月 日
【备注】
相关热词搜索: 操作系统 实验 报告 brcAAA