操作系统课设之基于信号量机制的并发程序设计
前言
课程设计开始了,实验很有意思,写博客总结学到的知识
白嫖容易,创作不易,学到东西才是真
本文原创,创作不易,转载请注明!!!
本文链接
个人博客:https://ronglin.fun/archives/183
PDF链接:见博客网站
CSDN: https://blog.csdn.net/RongLin02/article/details/118309933
为了美观,实验源代码在结尾处,整合版见下
链接:https://pan.baidu.com/s/1rXj1QJGuw-BVc5sQWret9w
提取码:Lin2
本次操作系统课程设计合集
操作系统课程设计源代码
本次操作系统课程设计合集
操作系统课设之Windows 进程管理
操作系统课设之Linux 进程管理
操作系统课设之Linux 进程间通信
操作系统课设之Windows 的互斥与同步
操作系统课设之内存管理
操作系统课设之虚拟内存页面置换算法的模拟与实现
操作系统课设之基于信号量机制的并发程序设计
操作系统课设之简单 shell 命令行解释器的设计与实现
仅用于学习,如有侵权,请联系我删除
实验题目
基于信号量机制的并发程序设计
实验目的
(1) 回顾操作系统进程、线程的有关概念,针对经典的同步、互斥、死锁与饥饿问题进行并发程序设计与实现。
(2) 理解互斥体对象,利用互斥与同步操作编写读者-写者问题的并发程序,加深对 P (即semWait)、V(即 semSignal)原语以及利用 P、V 原语进行进程间同步与互斥操作的理解。
(3) 理解 Linux 支持的信息量机制,利用 IPC 的信号量系统调用编程实现哲学家进餐问题。
总体设计
因为指导书上只写了完成其一即可,我选择的题目是在Windows下实现读者写者问题。
背景知识:
主要是熟悉Windows API,熟悉PV操作对应的语法结构
HANDLE WriteSemaphore; //定义信号量
WriteSemaphore = CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);//信号量初始化DWORD WINAPI reader(LPVOID); //定义线程的执行函数
DWORD readerID[READER_NUM]; //读者线程的标识符
CreateThread(NULL,0,reader,NULL,0,&readerID[i]); //启动线程//PV操作
WaitForSingleObject(XSemaphore,INFINITE); //semWait(x);
ReleaseSemaphore(XSemaphore,1,NULL); //semSignal(x);
还有就是对读者写者问题的理解,由于书上已经说的很详尽,而且还给了伪代码,这里只是浅谈一下。
读者写者问题:
存在一个多进程共享的数据区,该数据区可以是一个文件或一块内存空间,甚至可以是一组寄存器,有些进程(reader)只读取这个数据区中的数据,有些进程(writer)只往数据区中写数据。,此外,还必须满足:
1.任意数量的读进程可同时读这个文件。
2.一次只有一个写进程可以写文件
3.若写进程正在写文件,则禁止任何读进程读文件。
书上实现的读者优先的算法思路是:
写进程比较简单,信号量WriteSemaphore用于实施排斥,只要一个写进程正在访问数据区,其他写进程和读进程就都不能访问它。读进程也使用WriteSemaphore实施互斥,但为了允许多个读进程,没有读进程正在读时,第一个试图读的读进程需要在WriteSemaphore上等待。当至少已有一个读进程在读时,随后的读进程无须等待,可以直接进入。readcount用于记录读进程的数量,信号量XSemaphore用于确保readcount被正确地更新。
详细设计
主要是调用Windows的API
首先就是宏定义
#define MAX_READER_NUM 512 //最大读者数
#define READER_NUM 3 //读者数量
#define WRITER_NUM 2 //写者数量
#define MOD 100 //一个模数
解释一下模数的意义,为了测试读者写者的实际效果,我定义了一个test变量,当写者写的时候test自增1,为了防止自增次数太多导致数据溢出,就定义了一个模数,读者就负责读test数据。
读者线程执行:
void READUNIT()
{cout<<"一个读者开始阅读:";cout<<test<<endl;
}
写者线程写:
void WRITEUNIT()
{cout<<"写者开始写:";test = (test+1) % MOD;cout<<test<<endl;
}
这两个是读者写者执行的主要逻辑功能
然后就是读者线程的执行函数:
DWORD WINAPI reader(LPVOID lpPara)
{while(p_ccontinue){WaitForSingleObject(XSemaphore,INFINITE); //semWait(x);readcount++;if(readcount == 1) //第一个读者来了WaitForSingleObject(WriteSemaphore,INFINITE); //semWait(wsem);ReleaseSemaphore(XSemaphore,1,NULL); //semSignal(x);READUNIT();//阅读完毕WaitForSingleObject(XSemaphore,INFINITE); //semWait(x);readcount--;//无读者,释放资源if(readcount == 0)ReleaseSemaphore(WriteSemaphore,1,NULL); //semSignal(wsem);ReleaseSemaphore(XSemaphore,1,NULL); //semSignal(x);Sleep(3000);}return 0;
}
写者线程的执行函数
DWORD WINAPI writer(LPVOID lpPara)
{while(p_ccontinue){WaitForSingleObject(WriteSemaphore,INFINITE); //semWait(wsem);WRITEUNIT();ReleaseSemaphore(WriteSemaphore,1,NULL); //semSignal(wsem);Sleep(2000);}return 0;
}
实验结果与分析
结果如上,是符合预期的,读者只读test变量的数据,而写者对test变量自增。
小结与心得体会
本实验的难度不大,主要是熟悉Windows API用法,了解信号量的定义和初始化,线程的创建和PV操作,然后就是理解课本上对于读者写者问题的讲解。=w=
源代码
#include <windows.h>
#include <iostream>#define MAX_READER_NUM 512
#define READER_NUM 3
#define WRITER_NUM 2
#define MOD 100
using namespace std;int readcount = 0;
HANDLE WriteSemaphore; //实现读写互斥
HANDLE XSemaphore; //对于人数修改的互斥量
DWORD WINAPI reader(LPVOID); //读者线程
DWORD WINAPI writer(LPVOID); //写者线程
bool p_ccontinue = true; //控制程序结束int test = 0;int main()
{//初始化两个信号量/*结构体指针;信号量对象的初始计数;信号量对象的最大计数;信号量对象的名称*/WriteSemaphore = CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);XSemaphore = CreateSemaphore(NULL,1,MAX_READER_NUM,NULL);//用WindowsAPI模拟课本上 parbegin(reader,writer);//总的线程数HANDLE hThreads[READER_NUM + WRITER_NUM]; //各线程的 handleDWORD readerID[READER_NUM]; //读者线程的标识符DWORD writerID[WRITER_NUM]; //写者线程的标识符//创建读者线程for (int i=0; i<READER_NUM; i++){hThreads[i]=CreateThread(NULL,0,reader,NULL,0,&readerID[i]);if (hThreads[i]==NULL)return -1;}//创建写者线程for (int i=0; i<WRITER_NUM; i++){hThreads[READER_NUM+i]=CreateThread(NULL,0,writer,NULL,0,&writerID[i]);if (hThreads[i]==NULL)return -1;}while(p_ccontinue){if(getchar()) //按回车后终止程序运行{p_ccontinue = false;}}return 0;
}//读者阅读
void READUNIT()
{cout<<"一个读者开始阅读:";cout<<test<<endl;
}//写者写
void WRITEUNIT()
{cout<<"写者开始写:";test = (test+1) % MOD;cout<<test<<endl;
}
//读者
DWORD WINAPI reader(LPVOID lpPara)
{while(p_ccontinue){WaitForSingleObject(XSemaphore,INFINITE); //semWait(x);readcount++;if(readcount == 1) //第一个读者来了WaitForSingleObject(WriteSemaphore,INFINITE); //semWait(wsem);ReleaseSemaphore(XSemaphore,1,NULL); //semSignal(x);READUNIT();//阅读完毕WaitForSingleObject(XSemaphore,INFINITE); //semWait(x);readcount--;//无读者,释放资源if(readcount == 0)ReleaseSemaphore(WriteSemaphore,1,NULL); //semSignal(wsem);ReleaseSemaphore(XSemaphore,1,NULL); //semSignal(x);Sleep(3000);}return 0;
}
//写者
DWORD WINAPI writer(LPVOID lpPara)
{while(p_ccontinue){WaitForSingleObject(WriteSemaphore,INFINITE); //semWait(wsem);WRITEUNIT();ReleaseSemaphore(WriteSemaphore,1,NULL); //semSignal(wsem);Sleep(2000);}return 0;
}
操作系统课设之基于信号量机制的并发程序设计相关推荐
- 操作系统课设之简单 shell 命令行解释器的设计与实现
前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...
- 操作系统课设之虚拟内存页面置换算法的模拟与实现
前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...
- 操作系统课设之内存管理
前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...
- 操作系统课设之Windows 的互斥与同步
前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...
- 操作系统课设之Linux 进程间通信
前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...
- 操作系统课设之Linux 进程管理
前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...
- 操作系统课设之Windows 进程管理
前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...
- 操作系统课设--使用信号量解决生产者/消费者同步问题
山东大学操作系统课设lab3 实验三 使用信号量解决生产者/消费者同步问题(lab3) 实验目的 理解Nachos的信号量是如何实现的 生产者/消费者问题是如何用信号量实现的 在Nachos中是如何创 ...
- 操作系统课设--NACHOS试验环境准备、安装与MAKEFILE分析
山东大学操作系统课设lab1 实验一 NACHOS试验环境准备.安装与MAKEFILE分析(lab1) 实验环境: 分析记录: 1. 准备虚拟机下LINUX宿主操作系统环境 2. NACHOS实验代码 ...
最新文章
- default argument given of parameter 的问题
- bash: /opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin/arm-hisiv300-linux-gcc: 没有那个文件或目录。...
- win7安装git客户端和简单配置
- 贪心: Array Splitting(数列分段)(洛谷CF1175D)
- 事件冒泡控件示例(转载)
- 检测系列--YOLO系列
- python不同版本共存_多个python版本共存时的pip配置
- NOI提高级:排序算法
- EMUI10还有哪些看点?分布式技术能力、开放与工具链...
- 美团靠外卖和到店业务赚来的钱
- Ajax提交表单数据(包含文件)
- Gerrit 服务搭建和升级详解(包括 H2 数据库迁移 MySQL 步骤)
- 【声明】前方不设坑位,不收费!~ 我为NET狂官方学习计划
- solr之服务器搭建步骤
- 计算机专业学生,大三了找技术岗,怎么写一份好简历?内附269份简历模板
- PostScript 打印描述语言 介绍
- C变量的直接引用与间接引用区别
- Yocto系列讲解[理论篇] 45 - bb文件中函数实操演示(3)继承自己的class
- 安卓手机 ADB 操作指令
- Axure旋转原件或图片