操作系统原理实验报告
姓 名:
廖翔
学 院:
计算机科学与技术学院
专 业:
计算机类
班 级:
CS1906
学 号:
U201915116
指导教师:
周正勇
2021 年 1 月 8 日
分数
教师签名
目 录
共享内存与进程同步 ........................................................................1
1.1 实验目的........................................................................................................................1
1.2 实验内容........................................................................................................................1
1.3 实验设计........................................................................................................................1
1.3.1 开发环境....................................................................................................................1
1.3.2 实验设计....................................................................................................................1
1.4 实验调试........................................................................................................................3
1.4.1 实验步骤....................................................................................................................3
1.4.2 实验调试及心得........................................................................................................4
附录 实验代码..........................................................................................................................5
1
共享内存与进程同步
1.1 实验目的
1、 掌握 Linux 下共享内存的概念与使用方法;
2、 掌握环形缓冲的结构与使用方法;
3、 掌握 Linux 下进程同步与通信的主要机制。
1.2 实验内容
利用多个共享内存(有限空间)构成的环形缓冲,将源 文件复制到目标文
件,实现两个进程的誊抄。
1.3 实验设计
1.3.1 开发环境
操作系统: Ubuntu 18.04.6 LTS
CPU: Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz
开发环境: g++
开发工具: Visual Studio Code
1.3.2 实验设计
1. 将数据存入环形缓冲区伪代码
while(未结束){
获取字符 c;
P(s1);
c->缓冲区 end 位置;
(end+1)%N->end;
V(s2);
}
2. 从缓冲区中读取数据伪代码
2
while(未结束){
P(s2);
缓冲区 start 位置字符->c; //c 存储获取的字符
(start+1)%N->start;
V(s1);
}
3. 不同程序的两个进程共享内存和信号灯原理
在主程序中创建共享内存和信号灯,记住创建时的 key 值。在 GET 和
PUT 中,使用 key 值获取共享内存和信号灯的 id 号,即可达到共享内存的
目的。
4. 主程序
(1)创建一个大小为 10240 的内存共享缓冲区(shmid(shmget(SHMKEY,
shmsize, IPC_CREAT | 0666)) 和 大 小 为 4 的 长 度 内 存 共 享 缓 冲 区
lenid(shmget(LENKEY, 4, IPC_CREAT | 0666))并初始化。
(2) 创 建 信 号 灯 集 semid 并 初 始 化 (semget(SEMKEY, 2, IPC_CREAT |
0666)),集合中有两个信号灯,empty 和 full,初值分别为提前设定好的
MAX=10 和 0
(3)创建两个子进程 p1,p2。两个子进程都使用 execv 函数跳转到指定的可
执行文件中执行另外的程序。其中,p1 执行 get 程序,p2 执行 copy 程序
(4)主程序等待两个子进程执行完毕后删除信号灯和两个共享内存缓冲区。
5. GET
(1) 使 用 函 数 shmget 获 得 共 享 内 存 环 形 缓 冲 区 shmid 和
lenid(shmget(SHMKEY, shmsize, IPC_CREAT | 0666)),使用函数 semget 获得
信号灯集 semid(semget(SEMKEY, 2, IPC_CREAT | 0666))。
(2)打开要读入缓冲区的文件,形式为”rb”。通过 feek 函数,得到文件指
针从头到文件最后的偏移字节数,即文件的长度,通过这个能够获得各种形
式文件的长度,比如二进制文件
(3)利用 whlie 循环,每次根据缓冲区块的大小 1024 来读取文件传送到内
存共享缓冲区中。而长度共享缓冲区则为最后一次写到缓冲区的长度。
(4)每当缓冲区走完一轮便返回第一个从头开始,以此形成环形缓冲区,
这个操作通过取余即可实现。
(5)每当对缓冲区写入时,需要对 empty 进行 P 操作,完成后对 full 进行 V
3
操作。
6. PUT
(1) 使 用 函 数 shmget 获 得 共 享 内 存 环 形 缓 冲 区 shmid 和
lenid(shmget(SHMKEY, shmsize, IPC_CREAT | 0666)),使用函数 semget 获得
信号灯集 semid(semget(SEMKEY, 2, IPC_CREAT | 0666))。
(2)打开要写入的文件,形式为”wb”
(3)利用 while 循环,每次根据缓冲区块的大小 1024 来读取共享内存缓冲
区写入文件,并判断本次读取是否是文件的最后一块,如果是最后一块,根
据文件剩余大小写入。如果不是,则直接读取 1024 个字节写入文件。
(4)每当缓冲区走完一轮便返回第一个从头开始,以此形成环形缓冲区,
这个操作通过取余即可实现。
(5)每当对缓冲区写入时,需要对 empty 进行 P 操作,完成后对 full 进行 V
操作。
1.4 实验调试
1.4.1 实验步骤
1. 在同一目录下编辑 main.c,put.c,get.c 文件并编译链接成可执行文件
2. 创建 input.txt 文件,作为一个 txt 文件进行测试
3. 创建一个可执行文件 hello,作为一个二进制文件进行测试
4. 输入命令“./main”执行文件,在同一目录下会生成自己设定好的输出文件
5. 输入命令 cmp 比较两个文件的区别
具体实验步骤截图如下:
1. main 函数执行结果(input.txt 文件)