前言

课程设计开始了,实验很有意思,写博客总结学到的知识
白嫖容易,创作不易,学到东西才是真
本文原创,创作不易,转载请注明!!!
本文链接
个人博客: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;
}

操作系统课设之基于信号量机制的并发程序设计相关推荐

  1. 操作系统课设之简单 shell 命令行解释器的设计与实现

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  2. 操作系统课设之虚拟内存页面置换算法的模拟与实现

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  3. 操作系统课设之内存管理

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  4. 操作系统课设之Windows 的互斥与同步

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  5. 操作系统课设之Linux 进程间通信

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  6. 操作系统课设之Linux 进程管理

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  7. 操作系统课设之Windows 进程管理

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  8. 操作系统课设--使用信号量解决生产者/消费者同步问题

    山东大学操作系统课设lab3 实验三 使用信号量解决生产者/消费者同步问题(lab3) 实验目的 理解Nachos的信号量是如何实现的 生产者/消费者问题是如何用信号量实现的 在Nachos中是如何创 ...

  9. 操作系统课设--NACHOS试验环境准备、安装与MAKEFILE分析

    山东大学操作系统课设lab1 实验一 NACHOS试验环境准备.安装与MAKEFILE分析(lab1) 实验环境: 分析记录: 1. 准备虚拟机下LINUX宿主操作系统环境 2. NACHOS实验代码 ...

最新文章

  1. default argument given of parameter 的问题
  2. bash: /opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin/arm-hisiv300-linux-gcc: 没有那个文件或目录。...
  3. win7安装git客户端和简单配置
  4. 贪心: Array Splitting(数列分段)(洛谷CF1175D)
  5. 事件冒泡控件示例(转载)
  6. 检测系列--YOLO系列
  7. python不同版本共存_多个python版本共存时的pip配置
  8. NOI提高级:排序算法
  9. EMUI10还有哪些看点?分布式技术能力、开放与工具链...
  10. 美团靠外卖和到店业务赚来的钱
  11. Ajax提交表单数据(包含文件)
  12. Gerrit 服务搭建和升级详解(包括 H2 数据库迁移 MySQL 步骤)
  13. 【声明】前方不设坑位,不收费!~ 我为NET狂官方学习计划
  14. solr之服务器搭建步骤
  15. 计算机专业学生,大三了找技术岗,怎么写一份好简历?内附269份简历模板
  16. PostScript 打印描述语言 介绍
  17. C变量的直接引用与间接引用区别
  18. Yocto系列讲解[理论篇] 45 - bb文件中函数实操演示(3)继承自己的class
  19. 安卓手机 ADB 操作指令
  20. Axure旋转原件或图片

热门文章

  1. Android Toolbar样式定制详解
  2. 实现textarea限制输入字数
  3. Linux系统瘦身裁剪 续
  4. 程序员的搞笑日常,你们懂得!....
  5. 飞鸽传书2011真正把用户利益放在股东的利益
  6. 即时通讯飞鸽传书民意soft需求
  7. 【飞秋】做需求分析一点心得
  8. byte[]、sbyte[]、int[]以及Array的故事
  9. [图]美专家称人类可能永远无法飞出太阳系
  10. 程序员如何自我超越,教你一招