求助各位大神!!!操作系统中消费者—生产者的代码问题???

下面是实现操作系统消费者—生产者的代码
为什么运行结果里面每个生产者产生的第一个数据值都是一样的,第二个数据也一样.......,明明是用rand()取的随机种子值????

还有为什么消费者子线程一直没有结束???

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

//缓冲区结构
typedef struct Buffer
{
    DWORD data;     //数据
    int Number;     //线程序号
}*lpBuffer;

//生产者线程的工作代码
DWORD WINAPI ProducerThread(LPVOID p);
//消费者线程的工作代码
DWORD WINAPI ConsumerThread(LPVOID p);


//描述生产者-消费者的类
class sy_pc
{
private:
    int in;     //生产者使用的循环缓冲区的下标
    int out;    //消费者使用的循环缓冲区的下标
    int bcount; //循环缓冲区的个数
    HANDLE empty;   //指向生产者的私有信号量
    HANDLE full;    //指向消费者的私有信号量
    HANDLE mutex;   //指示互斥信号量
    lpBuffer buffer;    //指向一个循环缓冲区
public:
    sy_pc(int);     //构造函数
    int getbuffer(lpBuffer);    //从缓冲区取出一个“产品”
    int putbuffer(Buffer);      //向缓冲区放入一个“产品”
    ~sy_pc();       //析构函数
};


sy_pc::sy_pc(int c)
{
    in = 0;
    out = 0;
    bcount = c;
    empty = CreateSemaphore(NULL, bcount, bcount, "sempty");
    full= CreateSemaphore(NULL, 0, bcount, "sfull");
    mutex= CreateSemaphore(NULL, 1, 1, "smutex");
    buffer = new Buffer[bcount];
}

int sy_pc::getbuffer(lpBuffer Buf)
{
    WaitForSingleObject(full, INFINITE);
    WaitForSingleObject(mutex, INFINITE);
    *Buf = buffer[out];
    out = (out + 1) % bcount;
    ReleaseSemaphore(mutex, 1, NULL);
    ReleaseSemaphore(empty, 1, NULL);
    return out;
}

int sy_pc::putbuffer(Buffer b)
{
    WaitForSingleObject(empty, INFINITE);
    WaitForSingleObject(mutex, INFINITE);
    buffer[in]=b;
    in = (in + 1) % bcount;
    ReleaseSemaphore(mutex, 1, NULL);
    ReleaseSemaphore(full, 1, NULL);
    return in;
}

sy_pc::~sy_pc()
{
    delete[]buffer;
}
#include "P_C.h"

#define M 5     //假设有5个生产者
#define N 3     //假设有3个消费者
CRITICAL_SECTION cs_Screen;     //因多线程竞争屏幕,故设次临界区控制变量
sy_pc s_pc(10);     //定义全局变量,简化参数传递方式

void main()
{
    HANDLE hThread[100];    //假设最多创建100个线程
    int i, j, sum;
    DWORD ExitCode;
    InitializeCriticalSection(&cs_Screen);  //初始化临界区对象cs_Screen
    srand((unsigned int)time(NULL));    //使用当前时间为随机序列的“种子”
    for (i = 1, j = 0; i < M; i++, j++) //创建5个生产者线程
    {                                   //每个生产者线程执行ProducerThread()的代码
        hThread[j] = CreateThread(NULL, 0, ProducerThread, (LPVOID)&i, 0, NULL);
        Sleep(10);
    }
    for (i = 1; i <= N; i++, j++)   //创建3个消费者线程
    {                               //每个生产者线程执行ConsumerThread()的代码
        hThread[j] = CreateThread(NULL, 0, ConsumerThread, (LPVOID)&i, 0, NULL);
        Sleep(10);
    }
    while (true)    //主线程不断循环,直到所有子线程结束
    {
        EnterCriticalSection(&cs_Screen);//准备进入临界区
        cout << "主线程正在运行*******************" << endl;
        LeaveCriticalSection(&cs_Screen);//退出临界区
        Sleep(1000);
        for (i = 0, sum = 0; i < j; i++)//总共j个子线程
        {
            ExitCode = 0;
            GetExitCodeThread(hThread[i], &ExitCode);//获得子线程的退出码
            if (ExitCode == 1)  //如果该线程也结束,则统计入sum
                sum = sum + ExitCode;
        }
        if (sum == j)   //若所有子线程已经结束,则主线程也结束
            break;
    }
    cout << "所有子线程已经结束,主线程也将结束****************" << endl;
}


//生产者线程的工作代码
DWORD WINAPI ProducerThread(LPVOID p)
{
    int *ip = (int*)p;
    int ThreadNumber = *ip;
    int naptime, in;
    Buffer b;
    for (int i = 1; i <= 3*N; i++)  //每个生产者共生产9个产品放入缓冲区
    {
        b.data = rand();
        b.Number = ThreadNumber;
        in = s_pc.putbuffer(b);
        EnterCriticalSection(&cs_Screen);
        cout << "Producer" << ThreadNumber << "向缓冲区投放了第 "
            << i << " 个数据" << b.data << "。 in=" << in << endl;
        LeaveCriticalSection(&cs_Screen);
        naptime = 100 + rand() % 200;
        Sleep(naptime);
    }
    EnterCriticalSection(&cs_Screen);
    cout << "Producer" << ThreadNumber << " 运行完毕" << endl;
    LeaveCriticalSection(&cs_Screen);
    return 1;
}

//消费者线程的工作代码
DWORD WINAPI ConsumerThread(LPVOID p)
{ 
    int ThreadNumber = *((int*)p);
    int naptime, out;
    Buffer b;
    for (int i = 1; i <= 3*M; i++)  //每个消费者共获取15个产品后结束
    {
        out = s_pc.getbuffer(&b);
        EnterCriticalSection(&cs_Screen);
        cout << "Consumer" << ThreadNumber << "从缓冲区取得了第 "
            << i << " 个数据" << b.data;
        cout<<",它是Producer" <<b.Number << "存放的。out=" << out << endl; 
        LeaveCriticalSection(&cs_Screen);
        naptime = 100 + rand() % 200;
        Sleep(naptime);
    }
    EnterCriticalSection(&cs_Screen);
    cout << "Consumer" << ThreadNumber << " 运行完毕" << endl;
    LeaveCriticalSection(&cs_Screen);
    return 1;
}
``

https://blog.csdn.net/Blank_Tt/article/details/90198901