多生产者多消费者问题C/C++实现
/*
这里使用到几个常用函数:
#include<windows.h>
//信号量
HANDLE WINAPI CreateSemaphore(
_In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes //安全属性,如果为NULL则是默认安全属性
_In_ LONG lInitialCount,//信号量的初始值,要>=0且<=第三个参数
_In_ LONG lMaximumCount,//信号量的最大值
_In_opt_ LPCTSTR lpName //信号量的名称
);
return : 指向信号量的句柄,如果创建的信号量和已有的信号量重名,那么返回已经存在的信号量句柄
//p操作
DWORD WaitForSingleObject(
HANDLE hHandle, //等待对象的 handle(代表一个核心对象)。
DWORD dwMilliseconds //等待的最长时间。时间终了,即使 handle尚未成为激发状态,此函数也要返回。此值可以是0(代表立刻返回),也可以是 INFINITE代表无穷等待。
);
//V操作
BOOL WINAPI ReleaseSemaphore(
_In_ HANDLE hSemaphore, //信号量句柄
_In_ LONG lReleaseCount, //释放后,信号量增加的数目
_Out_opt_ LPLONG lpPreviousCount //信号量增加前的值存放的地址,如果不需要则为NULL
);
return 释放是否成功
_beginthreadex()
c语言库 #include<process.h> 中的函数, 用来创建一个线程
unsigned long _beginthreadex(
void *security, // 安全属性, 为NULL时表示默认安全性
unsigned stack_size, // 线程的堆栈大小, 一般默认为0
unsigned(_stdcall *start_address)(void *), // 所要启动的线程函数
void *argilist, // 线程函数的参数, 是一个void*类型, 传递多个参数时用结构体
unsigned initflag, // 新线程的初始状态,0表示立即执行,CREATE_SUSPENDED表示创建之后挂起
unsigned *threaddr // 用来接收线程ID
);
return // 成功返回新线程句柄, 失败返回0
*/
#include<string>
#include<iostream>
#include<process.h>
#include<windows.h>
using namespace std;
//HANDLE 设置句柄
//HANDLE mutex;//互斥信号量
//思考后你会发现,如果盘子容量为1;这个不需要互斥量也能实现进程互斥,该阻塞的时候还是阻塞;
HANDLE apple, orange, plate; //同步信号量 苹果 橘子 盘子
int buf_max; //缓冲池大小 盘子可以放几个水果
int product_apple = 0, product_orange = 0; //产品数量
//爸爸放苹果线程
unsigned __stdcall dadToApple(void *)
{
while (1) {
WaitForSingleObject(plate, INFINITE);//等待同步信号量empty INFINITE代表无穷等待
//WaitForSingleObject(mutex, INFINITE);//等待互斥信号量mutex INFINITE代表无穷等待
product_apple++;
cout << "爸爸放了一个苹果,苹果数量:" << product_apple << endl << endl;
Sleep(100);
//ReleaseSemaphore(mutex, 1, NULL);//释放互斥信号量mutex
ReleaseSemaphore(apple, 1, NULL);//释放同步信号量full
}
return 1;
}
//妈妈放橘子线程
unsigned __stdcall momToOrange(void *)
{
while(1) {
WaitForSingleObject(plate, INFINITE);//等待同步信号量empty INFINITE代表无穷等待
//WaitForSingleObject(mutex, INFINITE);//等待互斥信号量mutex INFINITE代表无穷等待
product_orange++;
cout << "妈妈放了一个橘子,橘子数量:" << product_orange << endl << endl;
Sleep(100);
//ReleaseSemaphore(mutex, 1, NULL);//释放互斥信号量mutex
ReleaseSemaphore(orange, 1, NULL);//释放同步信号量full
}
return 1;
}
//女儿吃苹果线程
unsigned __stdcall daughterEatApple(void *)
{
while (1) {
WaitForSingleObject(apple, INFINITE);//等待同步信号量full
//WaitForSingleObject(mutex, INFINITE);//等待互斥信号量mutex
product_apple--;
cout << "女儿吃了一个苹果,剩余苹果数量:" << product_apple << endl << endl;
Sleep(100);
//ReleaseSemaphore(mutex, 1, NULL);//释放互斥信号量mutex
ReleaseSemaphore(plate, 1, NULL);//释放信号量
}
return 2;
}
//儿子吃橘子线程
unsigned __stdcall sonEatOrange(void *)
{
while (1) {
WaitForSingleObject(orange, INFINITE);//等待同步信号量full
//WaitForSingleObject(mutex, INFINITE);//等待互斥信号量mutex
product_orange--;
cout << "儿子吃了一个橘子,剩余橘子数量:" << product_orange << endl << endl;
Sleep(100);
//ReleaseSemaphore(mutex, 1, NULL);//释放互斥信号量mutex
ReleaseSemaphore(plate, 1, NULL);//释放信号量
}
return 2;
}
int main()
{
bool flag = false;
while (!flag)
{
cout << "请输入盘子最多可以放几个水果(大于0):" << endl;
cin >> buf_max;
if (buf_max <= 0);
else flag = true;
}
//创建信号量
plate = CreateSemaphore(NULL, buf_max, buf_max, NULL);//初值化盘子容量
apple = CreateSemaphore(NULL, 0, buf_max, NULL); //初值为0,最大为盘子容量
orange = CreateSemaphore(NULL, 0, buf_max, NULL); //初值为0,最大为盘子容量
//mutex = CreateSemaphore(NULL, 1, 1, NULL); //初值为1,最大为1
HANDLE hth1, hth2, hth3, hth4; //线程句柄
//创建线程
hth1 = (HANDLE)_beginthreadex(NULL, 0, dadToApple, NULL, 0, NULL);
hth2 = (HANDLE)_beginthreadex(NULL, 0, momToOrange, NULL, 0, NULL);
hth3 = (HANDLE)_beginthreadex(NULL, 0, sonEatOrange, NULL, 0, NULL);
hth4 = (HANDLE)_beginthreadex(NULL, 0, daughterEatApple, NULL, 0, NULL);
//等待子线程结束
WaitForSingleObject(hth1, INFINITE);
WaitForSingleObject(hth2, INFINITE);
WaitForSingleObject(hth3, INFINITE);
WaitForSingleObject(hth4, INFINITE);
//关闭句柄
CloseHandle(hth1);
CloseHandle(hth2);
CloseHandle(hth3);
CloseHandle(hth4);
CloseHandle(plate);
CloseHandle(apple);
CloseHandle(orange);
//CloseHandle(mutex);
}