实验目的

分析进程的同步与互斥现象,编程实现经典的进程同步问题——生产者与消费者问题的模拟,进一步加深对进程同步与互斥的理解。

实验内容

用C语言实现对生产者与消费者问题的模拟。

实验原理

生产者和消费者是经典的进程同步问题,在这个问题中,生产者不断的向缓冲区中写入数据,而消费者则从缓冲区中读取数据。生产者进程和消费者对缓冲区的操作是互斥,即当前只能有一个进程对这个缓冲区进行操作,生产者进入操作缓冲区之前,先要看缓冲区是否已满,如果缓冲区已满,则它必须等待消费者进程将数据取出才能写入数据,同样的,消费者进程从缓冲区读取数据之前,也要判断缓冲区是否为空,如果为空,则必须等待生产者进程写入数据才能读取数据。

实验准备

实现步骤

  1. 分析计算机系统中对资源的分配与释放过程:计算机系统中的每个进程都可以消费或生产某类资源。当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。而当某个进程释放资源时,则它就相当一个生产者。
  2. 定义生产者消费者问题中的各数据结构,并初始化信号量。
  3. 创建生产者与消费者进程,利用信号量实现生产者与消费者之间的同步与互斥;最后编程实现。

相关函数

在实现的过程中需要用到以下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;
}

【操作系统】进程同步实验相关推荐

  1. 进程同步算法实现实验报告Linux,操作系统进程同步实验报告.doc

    操作系统进程同步实验报告 实验三:进程同步实验 一.实验任务: (1)掌握操作系统的进程同步原理: (2)熟悉linux的进程同步原语: (3)设计程序,实现经典进程同步问题. 二.实验原理: (1) ...

  2. 计算机操作系统进程同步实验报告,操作系统进程同步和互斥的实验报告

    操作系统进程同步和互斥的实验报告 (5页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 湖南农业大学信息科学技术学院学生实验报告姓名: 年级专 ...

  3. 计算机操作系统进程同步实验报告,操作系统-进程管理与进程同步-实验报告

    进程管理与进程同步实验报告 实验一.进程管理与进程同步 一.实验目的 了解进程管理的实现方法,理解和掌握处理进程同步问题的方法. 二.实验内容 实现银行家算法.进程调度过程的模拟.读者-写者问题的写者 ...

  4. 操作系统进程同步实验报告

    华侨大学计算机科学与技术学院 操作系统实验报告 进程同步 课程名称:操作系统实验 实验项目名称:进程同步 学    院:计算机科学与技术学院 专业班级: 姓    名: 学    号: 目录 1.描述 ...

  5. 山东大学linux实验四CSDN,山东大学操作系统实验报告材料4进程同步实验

    <山东大学操作系统实验报告材料4进程同步实验>由会员分享,可在线阅读,更多相关<山东大学操作系统实验报告材料4进程同步实验(15页珍藏版)>请在人人文库网上搜索. 1.实用标准 ...

  6. 操作系统原理实验-进程同步

    操作系统原理实验报告 实验题目 实验二进程同步 实验二.进程同步 1.1 实验目的 现代操作系统的核心是多道程序设计.多处理器和分布式处理器,这些方案和操作系统设计技术的基础都是并发.当多个进程并发执 ...

  7. linux进程同步互斥实验小结,操作系统进程同步互斥实验

    <操作系统进程同步互斥实验>由会员分享,可在线阅读,更多相关<操作系统进程同步互斥实验(7页珍藏版)>请在人人文库网上搜索. 1.进程的同步互斥实验进程的同步互斥实验进程的同步 ...

  8. 《操作系统》实验报告——熟悉Linux基础命令及进程管理

    理论知识 Linux--进程管理 Linux--Linux C语言编程基础知识 手把手教你安装Linux虚拟机 一.实验目的 (1)加深对进程概念的理解,明确进程和程序的区别. (2)进一步认识并发执 ...

  9. 计算机进程同步实验观察结果记录表,实验5 操作系统进程与文件管理 实验报告表 作业 5.doc...

    实验5操作系统进程与文件管理实验报告表 (本文档包含: 实验5 实验报告 与 第5周作业题) 实验5 操作系统进程与文件管理 实验报告 学号 1404505147 姓名禤雨骅 班级: 临床医学14(1 ...

  10. ZUCC_操作系统原理实验_实验九 消息队列

    操作系统原理实验报告 课程名称 操作系统原理实验 实验项目名称 实验九 消息队列 实验目的 了解 Linux 系统的进程间通信机构 (IPC): 理解Linux 关于消息队列的概念: 掌握 Linux ...

最新文章

  1. 支持向量机python代码_用TensorFlow实现多类支持向量机的示例代码
  2. android wps表格如何设置边框颜色
  3. 国家开放大学2021春1080工程数学(本)题目
  4. 宝马纯电动i4原型车谍照曝光 预计2021年上市
  5. [oracle 10g]命令行启动ORACLE服务及顺序
  6. 992. Sort Array By Parity II - LeetCode
  7. SQL Server分页3种方案比拼[转]
  8. 对外暴露Id异或加密解密
  9. 3. 请列举java ee的主要新特性_JavaEE考试题
  10. MATLAB代码:全面ADMM算法代码,实现了三种ADMM迭代方式 参考文档:《基于串行和并行ADMM算法的电_气能量流分布式协同优化_瞿小斌》
  11. CC2530外部中断控制LED灯开关
  12. CF大陆斗C战士(二)
  13. python绘制哆啦a梦实训报告_python画哆啦A梦和大雄
  14. NVENC/NVDEC 10bits 编程
  15. bzoj1605 洛谷2905 [Usaco2008 Open]Crisis on the Farm 牧场危机(DP)
  16. swift学习资料2022
  17. Android8.0以上打开相机并裁剪图片
  18. 【ESXi】失败 – “scsi0:0”的磁盘类型 2 不受支持或无效。请确保磁盘已导入
  19. 已知有十六支男子足球队参加2008北京奥运会。写一个程序,把这16支球队随机分为4个组。
  20. 手写sqrt 牛顿迭代法

热门文章

  1. java算法--冒泡算法
  2. mysql日期时间类型
  3. 浙江大学 PAT 编程初级2
  4. python编程控制机器人_基于Python开发的微信图灵机器人
  5. Linux系统rootfs切换到真正的根文件系统详细源码解析(附工作项目手动制作根文件实例)
  6. Your Freedom — 跨平台的代理软件
  7. batchsize、iteration、epoch之间的关系
  8. 苹果展开新显示器带动高阶需求:Mini LED背光技术
  9. NRF52832学习笔记(39)——设备信息服务(DIS)
  10. 集成google webview(android.7.1)