进程同步与进程通信(#include <windows.h>)

news2024/11/27 3:55:19

目录

实验二  进程同步与进程通信

一、实验目的

二、实验内容

任务一、进程同步与互斥

任务二、进程通信


实验二  进程同步与进程通信

备注:大二(下)操作系统实验二

一、实验目的

 掌握基本的同步与互斥算法,理解P,V操作

 学习使用Windows中基本的同步对象,掌握相关API的使用方法

了解Windows中多线程的并发执行机制,实现进程的同步与互斥

了解Wndows进程间通信方法的典型类型,如命名管道、文件映射等,掌握进程间通信的基本原理

了解windows系统环境下的进程通信机制,熟悉windows系统提供的进程通信API

二、实验内容

实验环境:DEV C++

任务一、进程同步与互斥

1、使用临界区对象模拟售票功能

其中SellPro_1, SellPro_2两个函数分别对应两个售票进程,一次售出一张票

#include <windows.h>
#include <iostream>
#define N 100
using namespace std;

DWORD WINAPI SellPro_1(LPVOID  lpParameter);
DWORD WINAPI SellPro_2(LPVOID  lpParameter );
DWORD WINAPI SellPro_3(LPVOID  lpParameter );

int tickets = N;

CRITICAL_SECTION critical_sec;//定义关键区域

DWORD WINAPI SellPro_1(LPVOID  lpParameter )
{
	while(TRUE)
	{
		Sleep(1);
		
		EnterCriticalSection( &critical_sec);
		//进入关键区域
		if(tickets>0)
		{
			cout<< "thread1 sell ticket, remain: "<<--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, remain: "<<--tickets<<endl;
		}
		else break;
		LeaveCriticalSection( &critical_sec);
		//离开关键区域
	}
	
	return 0;
}

int main()
{
	HANDLE hThread1;
	HANDLE hThread2;

	InitializeCriticalSection(&critical_sec);//初始化关健区域
	
	hThread1 = CreateThread(NULL,0,SellPro_1,NULL,0,NULL);
	hThread2 = CreateThread(NULL,0, SellPro_2,NULL,0,NULL);
	
	CloseHandle(hThread1);
	CloseHandle(hThread2);
	
	Sleep(4000);
	
	return 0;
}

 

2、使用信号量对象模拟售票功能

其中SellPro_1, SellPro_2两个函数分别对应两个售票进程,一次售出一张票

#include <windows.h>
#include <iostream>
using namespace std;

static HANDLE g_hSemaphore = INVALID_HANDLE_VALUE;
static int g_Count = 100;

DWORD WINAPI Thread_A(LPVOID lpParamter);
DWORD WINAPI Thread_B(LPVOID lpParamter);

DWORD WINAPI Thread_A(LPVOID lpParamter)
{
	long count;
	
	while(1)
	{
		WaitForSingleObject(g_hSemaphore,INFINITE);
		if(g_Count>0)
		cout<<"thread_A sell ticket, remain: "<<--g_Count<<endl;
		else break;
		ReleaseSemaphore(g_hSemaphore,1,&count);
		
		Sleep(10);
	}
	
	return 0;
}

DWORD WINAPI Thread_B(LPVOID lpParamter)
{
	long count;
	
	while(1)
	{
		WaitForSingleObject(g_hSemaphore,INFINITE);
		if(g_Count>0)
		cout<< "thread_B sell ticket, remain: "<<--g_Count<<endl;
		else break;
		ReleaseSemaphore(g_hSemaphore,1,&count);
		
		Sleep(10);
	}
	
	return 0;
}

int main(int argc, char** argv)
{
	HANDLE threadA = INVALID_HANDLE_VALUE;
	HANDLE threadB = INVALID_HANDLE_VALUE;
	
	g_hSemaphore = CreateSemaphore(NULL,1,20,TEXT( "semaphore"));
	
	threadA = CreateThread(NULL,0,Thread_A,NULL,0,NULL);
	threadB = CreateThread(NULL,0,Thread_B,NULL,0,NULL);
	
	system("pause");
	
	CloseHandle(threadA);
	CloseHandle(threadB);

	return 0;
}

3、简单的生产者--消费者问题

一个缓冲区,存放一个整型数据

#include <stdio.h>
#include <process.h>
#include <windows.h>

const int END_PRODUCE_NUMBER=20;
int g_Buffer;
CRITICAL_SECTION g_cs;
HANDLE g_hEventBufferEmpty, g_hEventBufferFull;

unsigned int __stdcall ProducerThreadFun(PVOID pM) //生产者进程
{
	int i;
	
	for (i=1;i<=END_PRODUCE_NUMBER;i++)
	{
		WaitForSingleObject(g_hEventBufferEmpty, INFINITE);
		EnterCriticalSection(&g_cs);
		g_Buffer=i;
		printf("生产者将数据%d放入缓冲区\n",i);
		LeaveCriticalSection(&g_cs);
		SetEvent(g_hEventBufferFull);
		
		Sleep (1000);
	}
	
	return 0;
}

unsigned int __stdcall ConsumerThreadFun(PVOID pM) //消费者进程
{
	int flag=1;
	
	while(flag)
	{		
		WaitForSingleObject(g_hEventBufferFull, INFINITE);
		EnterCriticalSection(&g_cs);
		printf("消费者从缓冲区中取出数据%d\n", g_Buffer);
		if(g_Buffer==END_PRODUCE_NUMBER) flag=0;
		LeaveCriticalSection(&g_cs);
		SetEvent(g_hEventBufferEmpty);
		
		Sleep(1000);
	}
	
	return 0;
}

int main()
{
	HANDLE hThread[2];
	
	printf("生产者消费者问题\n");
	
	InitializeCriticalSection(&g_cs);
	g_hEventBufferEmpty=CreateEvent(NULL, FALSE, TRUE, NULL);
	g_hEventBufferFull=CreateEvent(NULL, FALSE, FALSE, NULL);
	hThread[0]=(HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);
	hThread[1]= (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);
	WaitForMultipleObjects(2, hThread, TRUE, INFINITE);
	
	CloseHandle(hThread[0]);
	CloseHandle(hThread[1]);
	CloseHandle(g_hEventBufferEmpty);
	CloseHandle(g_hEventBufferFull);
	
	DeleteCriticalSection(&g_cs);
	
	return 0;
}

任务二、进程通信

服务程序server端每次发送两个100之内的整数

客户程序client端实现将两个整数相加,并输出加法计算式

// Server端 

#include <iostream>
#include <windows.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

int main(int argc, char *argv[])
{
	int nRetCode = 0;
	char szBuffer[3] ;
	
	system("color F0");
	
    // 创建一个特定大小的文件映射对象,名称为"ShareMemory"
	HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, "ShareMemory" );   // 第一个参数也可以是NULL
	
    // 将这个文件映射对象的文件视图映射到进程的地址空间
	LPVOID lpBase =MapViewOfFile( hMapping,FILE_MAP_WRITE|FILE_MAP_READ,0,0,0);
	
	srand((unsigned)time(NULL));
	
	while(1)
	{	
		szBuffer[0]=rand()%100;
		szBuffer[1]=rand()%100;
		szBuffer[2]='\0';
		printf("%d\t%d\n",szBuffer[0],szBuffer[1]);
		
		// 向视图中写入两个100之内的整数
        strcpy( (char* )lpBase, szBuffer);
        
		Sleep(1000) ;
	}
	
	Sleep(20000);
	UnmapViewOfFile(lpBase);
	CloseHandle(hMapping);
	
	return nRetCode;
}
// Client端 

#include <iostream>
#include <windows.h>
using namespace std;

int main(int argc, char *argv[])
{
	int nRetCode = 0;
	
	system("color EA");
	
	// 打开这个名称为"ShareMemory"的文件映射对象	
	HANDLE hMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL , "ShareMemory" );

	if (hMapping)
	{
		wprintf(L"%s \r\n",L"Success");
		
        // 把相同的文件映射视图映射到自己的地址空间中
		LPVOID lpBase =MapViewOfFile( hMapping,FILE_MAP_READ| FILE_MAP_WRITE,0,0,0);
		
		char szBuffer[20] = {0};
		while(1)
		{
 			// 从视图中读取服务进程所写入的数据
			strcpy (szBuffer, (char* )lpBase);
			printf("%d+%d=%d \n", szBuffer[ 0] , szBuffer[1], szBuffer[0]+szBuffer[1]);
			Sleep( 1000);
		}
		
		UnmapViewOfFile( lpBase);
		CloseHandle(hMapping);
	}
	
	else wprintf(L"%s",L"OpenMapping Error" );
	
	return nRetCode;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/627032.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

移植蓝牙芯片后,PCM 无声音问题记录

背景:投影仪项目上的蓝牙模组本地已经验证ok,送到客户那里发现HFP打电话没声音。 1. 客户平台是3566,android 11的环境, 该环境下其他的模组是可以的 2. 在3566上安装QQ, 波通VOIP电话后, 无阴影, 3. 通过示波器接收pcm 无波形输出, 问题分析查证 1.查看HCI log ,…

【LeetCode热题100】打卡第17天:接雨水全排列旋转图像

文章目录 【LeetCode热题100】打卡第17天&#xff1a;接雨水&全排列&旋转图像⛅前言 接雨水&#x1f512;题目&#x1f511;题解 全排列&#x1f512;题目&#x1f511;题解 旋转图像&#x1f512;题目&#x1f511;题解 【LeetCode热题100】打卡第17天&#xff1a;接雨…

Elasticsearch 中文分词器

IK 分词器 我们在ES中最常用的中文分词器就是IK分词器&#xff0c;其项目地址为&#xff1a;https://github.com/medcl/elasticsearch-analysis-ik 下载安装 下载地址&#xff1a; https://github.com/medcl/elasticsearch-analysis-ik/releases 下载时注意和es的版本对应&a…

Network 之十二 iPXE 源码、编译过程、Linker tables 机制、移植新驱动、固件使用

最近&#xff0c;正在学习 iPXE 源码&#xff0c;于是开始各种 Google 查找 iPXE 的资料进行学习。以下就是学习过程中一些感觉比较重要的点&#xff0c;特此记录&#xff0c;以备后续查阅。 起源 上世纪 90 年代初&#xff0c;网卡开始在其扩展卡上包含启动 ROM&#xff0c;每…

2023-6-9-一天一种设计模式

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f4a5;&#x1f4a5;&#x1f4a5;欢迎来到&#x1f91e;汤姆&#x1f91e;的csdn博文&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f49f;&#x1f49f;喜欢的朋友可以关注一下&#xf…

当在浏览器截屏过曝时,应该采取的措施

一、问题来源 屏幕打开了HDR模式后&#xff0c;浏览器在截图的一瞬间出现色彩错误 正常情况如下&#xff1a; HDR截图过曝后如下&#xff1a; 二、解决方法 1. 关闭屏幕HDR模式 桌面右键显示设置关闭HDR选项 2. 修改浏览器选项 地址栏输入 edge://flags&#xff08;Edg…

【Spring框架】初识Spirng

目录 Spring是什么&#xff1f;什么是容器&#xff1f;什么是IoC&#xff1f;传统开发ioc 开发(控制反转式程序开发) DI(依赖注入) Spring是什么&#xff1f; Spring指的是Spring Framework(Spring框架)&#xff0c;它是一个开源框架&#xff0c;有着活跃而庞大的社区&#xf…

支持无线连接的头戴式耳机,双音腔结构很好听,雷柏VH800上手

平时在PC上玩游戏&#xff0c;除了键鼠一类的操控设备很重要之外&#xff0c;耳机等音频设备也很重要&#xff0c;我用的是头戴式耳机&#xff0c;这种耳机现在有无线版本&#xff0c;用起来很方便&#xff0c;而且延迟很低&#xff0c;可以带来更好的声画同步效果&#xff0c;…

在unity中如何使用chatGPT让虚拟IP动起来

1、导入chatGpt 解决AI智能回答 请根据上一篇文章进行导入&#xff1a;如何使用ChatGPT在unity中进行低代码快速开发&#xff1f;_向视科技&#xff0c;让您看见未来&#xff08;nbhctec&#xff09;的博客-CSDN博客 2、文本也有转换工具 可导入unity 插件-RT-Voice PRO 2.…

【回眸】Python入门(五)基础语法列表和词典:Python如何消灭重复性劳动

前言 本篇博客为填坑篇&#xff0c;这个系列的上一篇竟然是2021年的9月30更新的&#xff0c;离谱&#xff0c;差点就到断更两周年纪念日了&#xff0c;后续逐渐走向填坑的每一天&#xff0c;继续创作&#xff0c;希望这个系列的专栏文章能帮助到更多有需要的人。 列表 什么是列…

C++算法:有向无环图拓扑排序(领接链表)

文章目录 前言一、邻接表二、代码1、生成图2、出度、入度计算3、拓扑排序 总结 前言 前文有向无环图实现游戏技能树中我们使用了矩阵存储图的关系&#xff0c;可以称之为邻接矩阵。显然&#xff0c;链表也是可以实现的。在图结构入门一文中&#xff0c;我们也提到了链表存储的…

湖南大学OS-2020(另一张)期末考试解析

【特别注意】 答案来源于wolf以及网络 是我在备考时自己做的&#xff0c;仅供参考&#xff0c;若有不同的地方欢迎讨论。 【试卷评析】 这张卷子很老了&#xff0c;我不知道具体的年份&#xff0c;部分题目可能有用。如果仔细研究应该会有所收获。 【试卷与答案】 一、选…

机器学习 | 决策树 Decision Tree | 概念向

参考视频&#xff1a;【小萌五分钟】机器学习 | 决策树 文章目录 &#x1f4da;决策树是什么&#xff08;根节点、叶子节点、分支、深度&#xff09;&#x1f4da;决策树&#xff1a;分类树——算法思想&#x1f4da;分类错误率&#xff0c;熵&#xff0c;基尼指数&#x1f407…

蓝库云|实体店搭建一套巡店管理系统,能让大型连锁店立竿见影

传统巡店工作存在许多问题特别是大型连锁店&#xff0c;包括工作效率低、数据收集不便捷、信息共享困难等。为了解决这些问题&#xff0c;蓝库云认为拥有一套巡店管理系统就显得非常重要了。 巡店管理系统具备以下特点&#xff1a;手机电脑数据同步、实时数据采集和记录、可定…

谷粒商城学习笔记(二):简介- 谷粒商城项目微服务架构图

目录 项目前置知识一、前后端分离开发&#xff0c;分为 内网部署 和 外网部署。二、用户是通过使用 客户端 来完成各种的功能三、网关的作用四、Sentiel组件五、Feign组件六、OAuth2.0认证中心七、SpringSecurity组件八、关于数据存储的解决方案九、定位bug十、注册中心十一、配…

IDEA 远程 Debug 调试,你可以不需要,但是要会

文章目录 前言配置IDEA设置启动脚本改造 细节细节1&#xff1a;停在本地断点&#xff0c;关闭程序后会继续执行吗细节2&#xff1a;jar包代码和本地不一致会怎么样&#xff1f;细节3&#xff1a;日志打印在哪里&#xff1f;细节4&#xff1a;调试时其他人会不会卡住&#xff1f…

湖南大学OS-2022期末考试解析

【特别注意】 答案来源于不确定的光子和wolf 是两位同学在备考时自己做的&#xff0c;仅供参考&#xff0c;若有不同的地方欢迎讨论。 【试卷评析】 这张卷子比较正&#xff0c;个人感觉能够代表接下来几年的考试方向。如果仔细研究应该会有所收获。 【试卷与答案】 一、&…

网络安全认证CISP、CISSP对比及分析

好多网络安全行业或者打算转行该行业的人在纠结学是考取CISP认证还是CISSP认证&#xff0c;作为从事多年网络安全培训认证业务的专家&#xff0c;对这两个认证还是非常了解的&#xff0c;下面是这两个认证的一个对比说明&#xff0c;希望能够帮助到大家更好地选择到适合自己的认…

湖南大学OS-2020期末考试解析

【特别注意】 答案来源于wolf以及网络 是我在备考时自己做的&#xff0c;仅供参考&#xff0c;若有不同的地方欢迎讨论。 【试卷评析】 这张卷子有点老了&#xff0c;部分题目可能有用。如果仔细研究应该会有所收获。 【试卷与答案】 一、选择题&#xff08;15%&#xff…

基于SSM+Vue的房屋租赁网站-求租合同设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…