实验四:进程同步与通信
一、实验目的:
1.掌握基本的同步与互斥算法,理解P,V操作。
2.理解生产者消费者模型,了解其它典型的同步互斥模型,如哲学家就餐、读者-写者模型等。
3.学习使用Windows中基本的同步对象,掌握相关API的使用方法。
4.了解Windows中多线程的并发执行机制,实现进程的同步与互斥。
5.Windows进程间通信的方法有很多,了解其中的典型类型,如命名管道、文件映射等,掌握进程间通信的基本原理。了解windows系统环境下的进程通信机制,熟悉windows系统提供的进程通信API。
二、实验环境:VC6.0
三、实验内容:
(写出主要的内容)
PART 1 进程同步与互斥
1.使用临界区对象,模拟售票功能。
(1)运行截图
(2)在分析程序运行结果的基础上,增加一个函数,模拟退票功能,并在主函数中加入适当的语句。
代码:
#include <windows.h>
#include
using namespace std;
DWORD WINAPI SellPro_1( LPVOID lpParameter);
DWORD WINAPI SellPro_2( LPVOID lpParameter );
DWORD WINAPI SellPro_3( LPVOID lpParameter );
int tickets=100;
CRITICAL_SECTION critical_sec; //定义关键区域
void main()
{
HANDLE hThread1;
HANDLE hThread2;
HANDLE hThread3;
InitializeCriticalSection(&critical_sec); //初始化关键区域
hThread1=CreateThread(NULL,0,SellPro_1,NULL,0,NULL);
hThread2=CreateThread(NULL,0,SellPro_2,NULL,0,NULL);hThread3=CreateThread(NULL,0,SellPro_3,NULL,0,NULL); CloseHandle(hThread1);
CloseHandle(hThread2);CloseHandle(hThread3);Sleep(4000);
}
DWORD WINAPI SellPro_1( LPVOID lpParameter )
{
while(TRUE)
{
Sleep(1);
EnterCriticalSection(&critical_sec); //进入关键代码区域
if(tickets>0)
{
cout<<"thread1 sell ticket : "<<–tickets<<endl;
}
else
break;
LeaveCriticalSection(&critical_sec); //离开代码关键区域
}
return 0;
}
DWORD WINAPI SellPro_2( LPVOID lpParameter)
{
while(TRUE)
{
Sleep(1);
EnterCriticalSection(&critical_sec); //进入关键代码区域
if(tickets>0)
{
cout<<"thread2 sell ticket : "<<–tickets<<endl;
}elsebreak;LeaveCriticalSection(&critical_sec); //离开代码关键区域
}
return 0;
}
DWORD WINAPI SellPro_3( LPVOID lpParameter)
{
while(TRUE)
{
Sleep(1);
EnterCriticalSection(&critical_sec); //进入关键代码区域
if(tickets>0)
{
cout<<"thread3 sell ticket : "<<++tickets<<endl;
}elsebreak;LeaveCriticalSection(&critical_sec); //离开代码关键区域
}
return 0;
}
运行截图:
2.使用信号量对象模拟售票功能。
(1)运行截图:
(2)将函数Thread_B中的语句Sleep(10);改为Sleep(20);,再分析程序运行结果。
分析:Thread_B延时20毫秒。Thread_A延时10毫秒
3.简单的生产者-消费者问题
(1)运行截图:
(2)修改程序,将每次产生的数据改为一个100之内的随机数。
修改的代码:
运行截图:
(3)修改程序,生产者进程中产生数据的个数不固定为20,如果无键盘输入事件,则一直循环产生数据,直到有键盘按下的操作才停止。相应的消费者进程中语句也需要修改。
提示:可使用kbhit( )函数判断有无键盘输入。
修改的代码:
4.在理解简单生产者-消费者程序的基础上,自己编程实现稍复杂的模型,将缓冲区改为能够存放若干个整数的数组,如int g_Buffer[N]; 其中N为一个整型常量。一个生产者,两个消费者。算法流程参考教材。
代码:
#include <stdio.h>
#include <process.h>
#include <windows.h>
BOOL SetConsoleColor(WORD wAttributes)
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole == INVALID_HANDLE_VALUE)
return FALSE;
return SetConsoleTextAttribute(hConsole, wAttributes);
}
const int END_PRODUCE_NUMBER = 8;
const int BUFFER_SIZE = 4;
int g_Buffer[BUFFER_SIZE];
int g_i, g_j;
CRITICAL_SECTION g_cs;
HANDLE g_hSemaphoreBufferEmpty, g_hSemaphoreBufferFull;
unsigned int __stdcall ProducerThreadFun(PVOID pM)
{
for (int i = 1; i <= END_PRODUCE_NUMBER; i++)
{
WaitForSingleObject(g_hSemaphoreBufferEmpty, INFINITE);
EnterCriticalSection(&g_cs);g_Buffer[g_i] = i;printf("生产者在缓冲池第%d个缓冲区中投放数据%d\n", g_i, g_Buffer[g_i]);g_i = (g_i + 1) % BUFFER_SIZE;LeaveCriticalSection(&g_cs);ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL);
}
printf("生产者完成任务,线程结束运行\n");
return 0;
}
unsigned int __stdcall ConsumerThreadFun(PVOID pM)
{
while (true)
{
WaitForSingleObject(g_hSemaphoreBufferFull, INFINITE);
EnterCriticalSection(&g_cs);SetConsoleColor(FOREGROUND_GREEN);printf(" 编号为%d的消费者从缓冲池中第%d个缓冲区取出数据%d\n", GetCurrentThreadId(), g_j, g_Buffer[g_j]);SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);if (g_Buffer[g_j] == END_PRODUCE_NUMBER){LeaveCriticalSection(&g_cs);ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL);break;}g_j = (g_j + 1) % BUFFER_SIZE;LeaveCriticalSection(&g_cs);Sleep(50); ReleaseSemaphore(g_hSemaphoreBufferEmpty, 1, NULL);
}
SetConsoleColor(FOREGROUND_GREEN);
printf(" 编号为%d的消费者收到通知,线程结束运行\n", GetCurrentThreadId());
SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
return 0;
}
int main()
{
InitializeCriticalSection(&g_cs);g_hSemaphoreBufferEmpty = CreateSemaphore(NULL, 4, 4, NULL);
g_hSemaphoreBufferFull = CreateSemaphore(NULL, 0, 4, NULL);
g_i = 0;
g_j = 0;
memset(g_Buffer, 0, sizeof(g_Buffer));const int THREADNUM = 3;
HANDLE hThread[THREADNUM];hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);
hThread[2] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);
WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE);
for (int i = 0; i < THREADNUM; i++)CloseHandle(hThread[i]);CloseHandle(g_hSemaphoreBufferEmpty);
CloseHandle(g_hSemaphoreBufferFull);
DeleteCriticalSection(&g_cs);
return 0;
}
运行截图:
PART 2 进程通信
共享内存文件映射方式
(1)运行截图:
(2)
(3)实现上述程序的控制停止功能,可以两种方式停止发送字符串:一种是服务器端发送10个字符串后便结束程序;另一种是用户在服务器端输入字符即结束程序。
修改的代码:
#include
#include <windows.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main(int argc, char *argv[])
{
int nRetCode = 0;
char szBuffer[20] ;
HANDLE hMapping = CreateFileMapping(NULL,NULL,PAGE_READWRITE,0,4096, "ShareMemory");
LPVOID lpBase = MapViewOfFile(hMapping,FILE_MAP_WRITE|FILE_MAP_READ,0,0,0);
srand((unsigned)time(NULL));
while(1)
{ for(int i=0;i<=9;i++)
szBuffer[i]=rand()%26+65;
szBuffer[10]=’\0’;
puts(szBuffer);
strcpy((char*)lpBase,szBuffer);
Sleep(1000);
break;
}
Sleep(20000);
UnmapViewOfFile(lpBase);
CloseHandle(hMapping);
return nRetCode;
}
实验四:进程同步与通信相关推荐
- 2020-10-29 实验四 进程同步与通信
实验四 进程同步与通信 一.实验目的: 二.实验环境: 三.实验内容: 四.心得体会: 一.实验目的: 1. 掌握基本的同步与互斥算法,理解P,V操作. 2. 理解生产者消费者模型,了解其它典型的同步 ...
- 【操作系统】实验四 进程同步与通信
目录 一.生产者消费者问题 代码1: 运行结果: 二.进程间的通信--软中断实现 代码2: 输出结果: 参考资料: 一.生产者消费者问题 代码1: 因为Linux系统中gcc编译环境下会发生内置函数找 ...
- 实验四 进程同步与通信(一)进程同步与互斥1
一.实验目的 1.掌握基本的同步与互斥算法,理解P,V操作. 2.理解生产者消费者模型,了解其它典型的同步互斥模型,如哲学家就餐.读者-写者模型等. 3.学习使用Windows中基本的同步对象,掌握相 ...
- 操作系统实验四 进程同步与互斥
一.实验目的: 掌握基本的同步与互斥算法,理解P,V操作. 理解生产者消费者模型,了解其它典型的同步互斥模型,如哲学家就餐.读者-写者模型等. 了解LINUX中进程同步互斥的实现方法,掌握相关函数的使 ...
- 山东大学linux实验四CSDN,山东大学操作系统实验报告材料4进程同步实验
<山东大学操作系统实验报告材料4进程同步实验>由会员分享,可在线阅读,更多相关<山东大学操作系统实验报告材料4进程同步实验(15页珍藏版)>请在人人文库网上搜索. 1.实用标准 ...
- 【正点原子FPGA连载】第十四章 串口通信实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1
1)实验平台:正点原子新起点V2开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609758951113 2)全套实验源码+手册+视频下载地址:ht ...
- 操作系统实验四——使用命名管道实现进程通信
操作系统实验四--使用命名管道实现进程通信 一. 实验目的 (1)了解windows系统环境下的进程通讯机制. (2)熟悉Windows系统提供的进程通信API. 二. 实验准备 相关API函数介绍 ...
- 《操作系统第四版》(刘振鹏 王煜)(四)进程同步与通信
操作系统(四) 四.进程同步与通信 4.1 进程间的相互作用 4.1.1进程间的联系 进程间的联系 资源共享关系 相互合作关系 临界资源 一种供多个进程互斥访问的资源 同一时刻只允许一个进程访问的资源 ...
- 2017-2018-2 20155228 《网络对抗技术》 实验四:恶意代码分析
2017-2018-2 20155228 <网络对抗技术> 实验四:恶意代码分析 1. 实践内容 1.1 系统运行监控 使用如计划任务,每隔一分钟记录自己的电脑有哪些程序在联网,连接的外部 ...
- 软件测试和系统试验,实验四 软件系统性测试
<实验四 软件系统性测试>由会员分享,可在线阅读,更多相关<实验四 软件系统性测试(9页珍藏版)>请在人人文库网上搜索. 1.软 件 学 院上 机 实 验 报 告课程名称: 软 ...
最新文章
- 希尔排序算法实现思想个人理解
- InnoDB Master Thread I/O Rate详解
- Ubuntu10.10 配置ssh服务器及samba服务器
- SAP Fiori + Vue = ?
- QString 与中文问题
- 也拿baidu搜索开玩笑!
- 在AWS RDS SQL Server中进行审核
- The word 'localhost' is not correctly spelled 这个问题怎么解决
- 云智能时代,开源软件的演进历程
- c++实现一个敏感词汇的程序_一个C++程序员生产力,大概相当20个C程序员,200个java程序员?...
- 利用WebMatrix安装drupal7 基于IID+SqlExpress
- java 生产mdb_Java生成mdb文件[MS Access文件]
- 那些年搞不懂的高深术语——依赖倒置•控制反转•依赖注入•面向接口编程【转】...
- “白发”位置竟暗示五脏六腑健康状况
- 【苹果推群发iMessage推】软件安装它起首将消息发送到Apple Push服务器,而后Apple Push服务器将消息发送到装配了应用程序的手机
- springboot前后端分离,邮箱/手机验证号激活和登录,手机注册和激活
- 怎样给蔬菜图片抠图?看看这个马路中央的紫茄子
- 消息队列的消费幂等性如何保证
- php读取excel的日期是数字,PHPExcel 解释 Excel日期得到纯数字 (含小数点) 的解决办法...
- 吉大c 语言程序设计奥鹏作业,吉大19年9月《C语言程序设计》作业考核试题