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

目录

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

一、实验目的

二、实验内容

任务一、进程同步与互斥

任务二、进程通信


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

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

一、实验目的

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

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

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

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

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

二、实验内容

实验环境:DEV C++

任务一、进程同步与互斥

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

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

#include 
#include 
#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<0)
		{
			cout<< "thread2 sell ticket, remain: "<<--tickets<

进程同步与进程通信(#include <windows.h>)_第1张图片 

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

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

#include 
#include 
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<0)
		cout<< "thread_B sell ticket, remain: "<<--g_Count<

进程同步与进程通信(#include <windows.h>)_第2张图片

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

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

#include 
#include 
#include 

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;
}

进程同步与进程通信(#include <windows.h>)_第3张图片

任务二、进程通信

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

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

// Server端 

#include 
#include 
#include 
#include 
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 
#include 
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;
}

进程同步与进程通信(#include <windows.h>)_第4张图片

你可能感兴趣的:(课程设计与实验,同步与互斥,进程通信)