【操作系统】进程同步实验
实验目的
分析进程的同步与互斥现象,编程实现经典的进程同步问题——生产者与消费者问题的模拟,进一步加深对进程同步与互斥的理解。
实验内容
用C语言实现对生产者与消费者问题的模拟。
实验原理
生产者和消费者是经典的进程同步问题,在这个问题中,生产者不断的向缓冲区中写入数据,而消费者则从缓冲区中读取数据。生产者进程和消费者对缓冲区的操作是互斥,即当前只能有一个进程对这个缓冲区进行操作,生产者进入操作缓冲区之前,先要看缓冲区是否已满,如果缓冲区已满,则它必须等待消费者进程将数据取出才能写入数据,同样的,消费者进程从缓冲区读取数据之前,也要判断缓冲区是否为空,如果为空,则必须等待生产者进程写入数据才能读取数据。
实验准备
实现步骤
- 分析计算机系统中对资源的分配与释放过程:计算机系统中的每个进程都可以消费或生产某类资源。当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。而当某个进程释放资源时,则它就相当一个生产者。
- 定义生产者消费者问题中的各数据结构,并初始化信号量。
- 创建生产者与消费者进程,利用信号量实现生产者与消费者之间的同步与互斥;最后编程实现。
相关函数
在实现的过程中需要用到以下API函数:
CreateThread
CreateThread()//该函数创建一个在调用进程的地址空间中执行的线程。若线程创建成功,将返回该线程的句柄。
函数原型
HANDLE CreateThread (
LPSECURITY_ATTRIBUTES lpThreadAttributes, //描述安全性,用NULL表示使用缺省值
DWORD dwStackSize,//新线程拥有自己的堆栈,0表示使用缺省值1MB,推荐
LPTHREAD_START_ROUTINE lpStartAddress, //新线程的起始地址,放线程函数名称
LPVOID lpParameter,//此值被传送到线程函数去作为参数
DWORD dwCreationFlags,//允许产生一个暂时挂起的线程,默认是0立即开始执行
LPDWORD lpThreadld );//新线程的ID被传到这
用法举例
hHandle1 = CreateThread( (LPSECURITY_ATTRIBUTES) NULL,0,(LPTHREAD_START_ROUTINE) ThreadName1,(LPVOID) NULL,0, &dwThreadID1 );
CreateMutex
CreateMutex()函数 可用来创建一个有名或无名的互斥量对象,函数返回值为互斥对象的句柄。其函数原型为:
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针,为NULL时,信号量得到一个默认的安全描述
BOOL bInitialOwner, // 初始化互斥对象的所有者
LPCTSTR lpName); // 指向互斥对象名
用法举例
handle g_hMutex;
g_hMutex = CreateMutex(NULL,FALSE,”mutexname1”);
ReleaseMutex
ReleaseMutex()该函数放弃指定互斥对象的拥有权。每使用一次,MUTEX引用计数自加1;
函数原型
BOOL ReleaseMutex(
HANDLE hMutex //想要释放的信号量句柄
);
HANDLE hHandle1=NULL;
BOOL rc;
rc = ReleaseMutex(hHandle1);
CreateSemaphore
CreateSemaphore()是创建信号量,返回信号量对象的句柄。
函数原型
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // 安全属性指针
LONG lInitialCount, // 初始计数
LONG lMaximumCount, // 最大计数
LPCTSTR lpName // 对象名
);
用法举例
static HANDLE hHandle1=NULL;
hHandle1=CreateSemaphore(NULL,0,1,"SemaphoreName1");
ReleaseSemaphore
ReleaseSemaphore()是增加信号量
函数原型
BOOL ReleaseSemaphore(
HANDLE hSemaphore, // 信号量句柄
LONG lReleaseCount, // 计数递增数量
LPLONG lpPreviousCount // 先前计数
);
用法举例
HANDLE hHandle1=NULL;
BOOL rc;
rc=ReleaseSemaphore(hHandle1,1,NULL);
WaitForSingleObject
WaitForSingleObject 函数功能:(用来检测handle事件的信号状态)当如下情况之一发生时该函数返回:指定对象处于信号态;超时。
函数原型
DWORD WaitForSingleObject(
HANDLE hHandle,//等待对象的线程HANDLE,或者仅仅是一个句柄,如信号量
DWORD dwMilliseconds //如果输入INFINITE,则无穷等待,直到HANDLE激活为止
);
用法举例
static HANDLE hHandle1=NULL;
DWORD dRes,;
dRes=WaitForSingleObject(hHandle1,INFINITE);
Sleep
Sleep函数功能:该函数对于指定的时间间隔挂起当前的执行线程。
函数原型
VOID Sleep(DWORD dwMilliseconds);
//里面填入要挂起的时间间隔,以毫秒为单位
实验过程
源代码
#include <windows.h>
#include <iostream>
using namespace std;
const int SIZE_OF_BUFFER = 5; //缓冲区长度
int ProductID = 0; //生产的产品号
int ConsumeID = 0; //将被消耗的产品号
int in = 0; //产品进缓冲区时的缓冲区下标
int out = 0; //产品出缓冲区时的缓冲区下标 int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列
bool g_continue = true; //控制程序结束
HANDLE g_hMutex; //用于线程间的互斥
HANDLE g_hFullSemaphore; //当缓冲区满时迫使生产者等待
HANDLE g_hEmptySemaphore; //当缓冲区空时迫使消费者等待 //生产一个产品。把新生产的产品放入缓冲区
void Produce()
{ cout<<"生产了一个产品:"<<++ProductID<<endl;g_buffer[in] = ProductID; in = (in+1)%SIZE_OF_BUFFER; //输出缓冲区当前的状态 for (int i=0;i<SIZE_OF_BUFFER;++i){ cout << i <<": " << g_buffer[i]; if (i==in) cout << " <-- 生产"; if (i==out) cout << " <-- 消费"; cout << endl; }cout << endl;
} //从缓冲区中取出一个产品,消耗一个产品
void Consume()
{ cout<<"消耗了一个产品:"<<g_buffer[out]<<endl;g_buffer[out]=0; out = (out+1)%SIZE_OF_BUFFER; //输出缓冲区当前的状态 for (int i=0;i<SIZE_OF_BUFFER;++i){ cout << i <<": " << g_buffer[i]; if (i==in) cout << " <-- 生产"; if (i==out) cout << " <-- 消费"; cout << endl; } cout << endl;
} //生产者线程
DWORD WINAPI Producer(LPVOID lpPara)
{ while(g_continue){ WaitForSingleObject(g_hEmptySemaphore,INFINITE); //申请空缓冲区WaitForSingleObject(g_hMutex,INFINITE); //互斥访问缓冲区Produce(); Sleep(2000); ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hFullSemaphore,1,NULL); } return 0;
} //消费者线程
DWORD WINAPI Consumer(LPVOID lpPara)
{ while(g_continue){ WaitForSingleObject(g_hFullSemaphore,INFINITE); WaitForSingleObject(g_hMutex,INFINITE); Consume(); Sleep(2000); ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hEmptySemaphore,1,NULL); } return 0;
} int main()
{ //创建各个互斥和同步信号 g_hMutex = CreateMutex(NULL,FALSE,NULL); g_hFullSemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER,NULL); g_hEmptySemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER,SIZE_OF_BUFFER,NULL); //调整生产者线程和消费者线程的个数,看看结果有何不同。const int PRODUCERS_COUNT = 6; //生产者的个数 const int CONSUMERS_COUNT = 2; //消费者的个数 //总的线程数 const int THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT; HANDLE hThreads[THREADS_COUNT]; //各线程的handle DWORD producerID[PRODUCERS_COUNT]; //生产者线程的标识符 DWORD consumerID[CONSUMERS_COUNT]; //消费者线程的标识符 //创建生产者线程 for (int i=0;i<PRODUCERS_COUNT;++i){ hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]); if (hThreads[i]==NULL) return -1; } //创建消费者线程 for (int j=0;j<CONSUMERS_COUNT;++j){ hThreads[PRODUCERS_COUNT+j]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[j]); if (hThreads[j]==NULL) return -1; } while(g_continue){ if(getchar()){ //按回车后终止程序运行 g_continue = false; } } return 0;
}
【操作系统】进程同步实验相关推荐
- 进程同步算法实现实验报告Linux,操作系统进程同步实验报告.doc
操作系统进程同步实验报告 实验三:进程同步实验 一.实验任务: (1)掌握操作系统的进程同步原理: (2)熟悉linux的进程同步原语: (3)设计程序,实现经典进程同步问题. 二.实验原理: (1) ...
- 计算机操作系统进程同步实验报告,操作系统进程同步和互斥的实验报告
操作系统进程同步和互斥的实验报告 (5页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 湖南农业大学信息科学技术学院学生实验报告姓名: 年级专 ...
- 计算机操作系统进程同步实验报告,操作系统-进程管理与进程同步-实验报告
进程管理与进程同步实验报告 实验一.进程管理与进程同步 一.实验目的 了解进程管理的实现方法,理解和掌握处理进程同步问题的方法. 二.实验内容 实现银行家算法.进程调度过程的模拟.读者-写者问题的写者 ...
- 操作系统进程同步实验报告
华侨大学计算机科学与技术学院 操作系统实验报告 进程同步 课程名称:操作系统实验 实验项目名称:进程同步 学 院:计算机科学与技术学院 专业班级: 姓 名: 学 号: 目录 1.描述 ...
- 山东大学linux实验四CSDN,山东大学操作系统实验报告材料4进程同步实验
<山东大学操作系统实验报告材料4进程同步实验>由会员分享,可在线阅读,更多相关<山东大学操作系统实验报告材料4进程同步实验(15页珍藏版)>请在人人文库网上搜索. 1.实用标准 ...
- 操作系统原理实验-进程同步
操作系统原理实验报告 实验题目 实验二进程同步 实验二.进程同步 1.1 实验目的 现代操作系统的核心是多道程序设计.多处理器和分布式处理器,这些方案和操作系统设计技术的基础都是并发.当多个进程并发执 ...
- linux进程同步互斥实验小结,操作系统进程同步互斥实验
<操作系统进程同步互斥实验>由会员分享,可在线阅读,更多相关<操作系统进程同步互斥实验(7页珍藏版)>请在人人文库网上搜索. 1.进程的同步互斥实验进程的同步互斥实验进程的同步 ...
- 《操作系统》实验报告——熟悉Linux基础命令及进程管理
理论知识 Linux--进程管理 Linux--Linux C语言编程基础知识 手把手教你安装Linux虚拟机 一.实验目的 (1)加深对进程概念的理解,明确进程和程序的区别. (2)进一步认识并发执 ...
- 计算机进程同步实验观察结果记录表,实验5 操作系统进程与文件管理 实验报告表 作业 5.doc...
实验5操作系统进程与文件管理实验报告表 (本文档包含: 实验5 实验报告 与 第5周作业题) 实验5 操作系统进程与文件管理 实验报告 学号 1404505147 姓名禤雨骅 班级: 临床医学14(1 ...
- ZUCC_操作系统原理实验_实验九 消息队列
操作系统原理实验报告 课程名称 操作系统原理实验 实验项目名称 实验九 消息队列 实验目的 了解 Linux 系统的进程间通信机构 (IPC): 理解Linux 关于消息队列的概念: 掌握 Linux ...
最新文章
- 支持向量机python代码_用TensorFlow实现多类支持向量机的示例代码
- android wps表格如何设置边框颜色
- 国家开放大学2021春1080工程数学(本)题目
- 宝马纯电动i4原型车谍照曝光 预计2021年上市
- [oracle 10g]命令行启动ORACLE服务及顺序
- 992. Sort Array By Parity II - LeetCode
- SQL Server分页3种方案比拼[转]
- 对外暴露Id异或加密解密
- 3. 请列举java ee的主要新特性_JavaEE考试题
- MATLAB代码:全面ADMM算法代码,实现了三种ADMM迭代方式 参考文档:《基于串行和并行ADMM算法的电_气能量流分布式协同优化_瞿小斌》
- CC2530外部中断控制LED灯开关
- CF大陆斗C战士(二)
- python绘制哆啦a梦实训报告_python画哆啦A梦和大雄
- NVENC/NVDEC 10bits 编程
- bzoj1605 洛谷2905 [Usaco2008 Open]Crisis on the Farm 牧场危机(DP)
- swift学习资料2022
- Android8.0以上打开相机并裁剪图片
- 【ESXi】失败 – “scsi0:0”的磁盘类型 2 不受支持或无效。请确保磁盘已导入
- 已知有十六支男子足球队参加2008北京奥运会。写一个程序,把这16支球队随机分为4个组。
- 手写sqrt 牛顿迭代法
热门文章
- java算法--冒泡算法
- mysql日期时间类型
- 浙江大学 PAT 编程初级2
- python编程控制机器人_基于Python开发的微信图灵机器人
- Linux系统rootfs切换到真正的根文件系统详细源码解析(附工作项目手动制作根文件实例)
- Your Freedom — 跨平台的代理软件
- batchsize、iteration、epoch之间的关系
- 苹果展开新显示器带动高阶需求:Mini LED背光技术
- NRF52832学习笔记(39)——设备信息服务(DIS)
- 集成google webview(android.7.1)