一、实验目的:
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 <iostream>
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;
}
else
break;
LeaveCriticalSection(&critical_sec);
//离开代码关键区域
}
return 0;
}
DWORD WINAPI SellPro_3(
LPVOID lpParameter)
{
while(TRUE)
{
Sleep(3);
EnterCriticalSection(&critical_sec);
//进入关键代码区域
if(tickets>0)
{
cout<<"\treturn ticket :
"<<++tickets<<endl;
}
else
break;
LeaveCriticalSection(&critical_sec);
//离开代码关键区域
}
return 0;
}
运行截图:
2.使用信号量对象模拟售票功能。
(1)运行截图:
(2) 将函数Thread_B中的语句Sleep(10);改为Sleep(20);,再分析程序运行结果。
运行截图:
分析:运行两次thread_A后再运行一次thread_B。
3 . 简单的生产者-消费者问题
(1)运行截图:
(2)修改程序,将每次产生的数据改为一个100之内的随机数。
修改的代码:
#include <stdio.h>
#include <process.h>
#include <windows.h>
#include<stdlib.h>
#include<time.h>
int END_PRODUCE_NUMBER=1;
int g_Buffer;
CRITICAL_SECTION g_cs;
HANDLE g_hEventBufferEmpty,g_hEventBufferFull;
unsigned int __stdcall ProducerThreadFun(PVOID pM) //生产者进程
{
int i;</