一、实验目的:
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;
}

实验四:进程同步与通信相关推荐

  1. 2020-10-29 实验四 进程同步与通信

    实验四 进程同步与通信 一.实验目的: 二.实验环境: 三.实验内容: 四.心得体会: 一.实验目的: 1. 掌握基本的同步与互斥算法,理解P,V操作. 2. 理解生产者消费者模型,了解其它典型的同步 ...

  2. 【操作系统】实验四 进程同步与通信

    目录 一.生产者消费者问题 代码1: 运行结果: 二.进程间的通信--软中断实现 代码2: 输出结果: 参考资料: 一.生产者消费者问题 代码1: 因为Linux系统中gcc编译环境下会发生内置函数找 ...

  3. 实验四 进程同步与通信(一)进程同步与互斥1

    一.实验目的 1.掌握基本的同步与互斥算法,理解P,V操作. 2.理解生产者消费者模型,了解其它典型的同步互斥模型,如哲学家就餐.读者-写者模型等. 3.学习使用Windows中基本的同步对象,掌握相 ...

  4. 操作系统实验四 进程同步与互斥

    一.实验目的: 掌握基本的同步与互斥算法,理解P,V操作. 理解生产者消费者模型,了解其它典型的同步互斥模型,如哲学家就餐.读者-写者模型等. 了解LINUX中进程同步互斥的实现方法,掌握相关函数的使 ...

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

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

  6. 【正点原子FPGA连载】第十四章 串口通信实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1

    1)实验平台:正点原子新起点V2开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609758951113 2)全套实验源码+手册+视频下载地址:ht ...

  7. 操作系统实验四——使用命名管道实现进程通信

    操作系统实验四--使用命名管道实现进程通信 一. 实验目的 (1)了解windows系统环境下的进程通讯机制. (2)熟悉Windows系统提供的进程通信API. 二. 实验准备 相关API函数介绍 ...

  8. 《操作系统第四版》(刘振鹏 王煜)(四)进程同步与通信

    操作系统(四) 四.进程同步与通信 4.1 进程间的相互作用 4.1.1进程间的联系 进程间的联系 资源共享关系 相互合作关系 临界资源 一种供多个进程互斥访问的资源 同一时刻只允许一个进程访问的资源 ...

  9. 2017-2018-2 20155228 《网络对抗技术》 实验四:恶意代码分析

    2017-2018-2 20155228 <网络对抗技术> 实验四:恶意代码分析 1. 实践内容 1.1 系统运行监控 使用如计划任务,每隔一分钟记录自己的电脑有哪些程序在联网,连接的外部 ...

  10. 软件测试和系统试验,实验四 软件系统性测试

    <实验四 软件系统性测试>由会员分享,可在线阅读,更多相关<实验四 软件系统性测试(9页珍藏版)>请在人人文库网上搜索. 1.软 件 学 院上 机 实 验 报 告课程名称: 软 ...

最新文章

  1. 希尔排序算法实现思想个人理解
  2. InnoDB Master Thread I/O Rate详解
  3. Ubuntu10.10 配置ssh服务器及samba服务器
  4. SAP Fiori + Vue = ?
  5. QString 与中文问题
  6. 也拿baidu搜索开玩笑!
  7. 在AWS RDS SQL Server中进行审核
  8. The word 'localhost' is not correctly spelled 这个问题怎么解决
  9. 云智能时代,开源软件的演进历程
  10. c++实现一个敏感词汇的程序_一个C++程序员生产力,大概相当20个C程序员,200个java程序员?...
  11. 利用WebMatrix安装drupal7 基于IID+SqlExpress
  12. java 生产mdb_Java生成mdb文件[MS Access文件]
  13. 那些年搞不懂的高深术语——依赖倒置•控制反转•依赖注入•面向接口编程【转】...
  14. “白发”位置竟暗示五脏六腑健康状况
  15. 【苹果推群发iMessage推】软件安装它起首将消息发送到Apple Push服务器,而后Apple Push服务器将消息发送到装配了应用程序的手机
  16. springboot前后端分离,邮箱/手机验证号激活和登录,手机注册和激活
  17. 怎样给蔬菜图片抠图?看看这个马路中央的紫茄子
  18. 消息队列的消费幂等性如何保证
  19. php读取excel的日期是数字,PHPExcel 解释 Excel日期得到纯数字 (含小数点) 的解决办法...
  20. 吉大c 语言程序设计奥鹏作业,吉大19年9月《C语言程序设计》作业考核试题

热门文章

  1. Linux内核分析 期中总结
  2. Vue element 自定义表单验证(验证联系方式、邮箱、邮政编码)
  3. WebSocket 结合 Nginx 实现域名及 WSS 协议访问
  4. debian live-buid
  5. FTP网络主机间文件传输指令
  6. 微软的黑屏说明了什么?
  7. 网络攻击与防御(一)
  8. 下雪js特效源码,网页下雪源码,圣诞节下雪代码,下雪代码,下雪特效源码
  9. ABS系统的Simulink仿真
  10. Flutter安装详解 as版本