这是一个兔子吃草同步算法的c++程序,如果对其中函数有不理解的可以看我另一篇博客进程相关函数汇总解释,对照着看,可能方便你理解、
过程图:
#include<Windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
/*信号量的定义,它是负责协调各个线程,以保证它们能够正确、合理的使用公共资源,用于控制进程间的同步或互斥*/
typedef HANDLE Semaphore;
Semaphore g_semBuffer, g_semGlass, g_mutex;//mutex为互斥锁
//利用Windows下的API函数(视窗操作系统应用程序接口)来定义P、V操作
#define P(S) WaitForSingleObject(S,INFINITE)
#define V(S) ReleaseSemaphore(S,1,NULL)
#define rate 100
#define CONSUMER_NUM 4 //消费者个数
#define PRODUCER_NUM 4 //生产者个数
#define BUFFER_NUM 4 //缓冲区个数
char *thing[4] = { "glass1","glass2","glass3","glass4" };
//公共的队列缓冲区
struct Buffer
{
int product[BUFFER_NUM];
int front, rear;
}g_buf;
//兔子进程
DWORD WINAPI Rabbit(LPVOID para)
{
srand((unsigned)time(NULL));
int i = *(int*)para; //第i只小白兔
int ptr; //兔子待吃的草的指针
Sleep(1800);
while (1)
{
printf("%03d 小白兔:我饿了......!\n",i);
P(g_semGlass);
P(g_mutex);
ptr = g_buf.front; //记录草在缓冲队列中的位置
g_buf.front = (g_buf.front + 1) % BUFFER_NUM;
V(g_mutex);
Sleep(rate*rand()%10+1800);
printf("%03d 小白兔:我吃了 buf[%d]=%s的草\n",i,ptr,thing[g_buf.product[ptr]]);
V(g_semBuffer);
}
return 0;
}
DWORD WINAPI Grassplot(LPVOID para)
{
int i = *(int*)para - CONSUMER_NUM;
int ptr;
int data;//产品
Sleep(1800);
printf("%03d 小草:小白兔快来找我!\n",i);
srand((unsigned)time(NULL));//让每次生成随机数不同,只使用rand会让每次的随机都是一样的
while (1)
{
Sleep(rate * rand() % 10 + 1800);
data = rand() % 4; //产生0到4间的整数
printf("%03d 小草:我要长大!data=%s!\n",i,thing[data]);
P(g_semBuffer);
P(g_mutex);
ptr = g_buf.rear; //记录消费的物品
g_buf.rear = (g_buf.rear + 1) % BUFFER_NUM;//入队
V(g_mutex);
g_buf.product[ptr] = data;
Sleep(rate / 2 * rand() % 10 + 1800);
printf("%03d 小草:我长大了!草放在buf[%d]=%s中,小白兔快来吃我!\n",i,ptr,thing[g_buf.product[ptr]]);
V(g_semGlass);
}
return 0;
}
int main()
{
HANDLE hThread[CONSUMER_NUM + PRODUCER_NUM];//线程计数
int totalThreads = CONSUMER_NUM + PRODUCER_NUM;
DWORD tid;
int i = 0;
//初始化信号量
g_mutex = CreateSemaphore(NULL,BUFFER_NUM,BUFFER_NUM,TEXT("mutexOfConsumerAndProducer"));
g_semBuffer = CreateSemaphore(NULL,BUFFER_NUM,BUFFER_NUM,TEXT("BufferSemaphone"));
g_semGlass = CreateSemaphore(NULL, 0, BUFFER_NUM, TEXT("ProductSemaphone"));
if (!g_semBuffer||!g_semGlass||!g_mutex)
{
printf("Create Semaphone Error!\n");
return -1;
}
//开启兔子的进程
printf("先请小白兔就位!\n");
for (i=0;i<CONSUMER_NUM;i++)
{
hThread[i] = CreateThread(NULL,0,Rabbit,&i,0,&tid);
if (hThread[i])
{
WaitForSingleObject(hThread[i], 100);
}
}
//开启草地进程
printf("请小草就位!\n");
for (; i<totalThreads; i++)
{
hThread[i] = CreateThread(NULL,0,Grassplot,&i,0,&tid);
if (hThread[i])
{
WaitForSingleObject(hThread[i],100);
}
}
//兔子线程和草地进程互斥的执行
WaitForMultipleObjects(totalThreads, hThread,TRUE, INFINITE);
return 0;
}