雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

生产者消费者模型

Posted on 2014-03-08 22:54  huhuuu  阅读(185)  评论(0编辑  收藏  举报

  在消费者模型里面,有两个主意点:

  1、对于当前消费次数的修改访问需要线程互斥,所以用关键段(也可以是互斥量)进行互斥。

  2、需要两个信号量(当然也可以是事件),一个表示缓冲区为空,一个表示缓冲区不为空,用于进程间的同步。

 

  还有一点:注意主线程的结束会导致子线程的结束!!!这里一开始一直没搞清楚,后来才发现在将主线程暂停!

  

#include<stdio.h>
#include<process.h>
#include<windows.h>

volatile  long g_nLoginCount;
const int THREAD_NUM = 10;
volatile  long g_num;

CRITICAL_SECTION g_thread;
HANDLE g_Semaphore_full,g_Semaphore_empty; //信号量

int num=10;

unsigned int __stdcall producer(void *pPM){

    int i;
    for(i=0;i<10;i++){

        WaitForSingleObject(g_Semaphore_empty,INFINITE);
        EnterCriticalSection(&g_thread);//对于g_num因为是共享的数据,需要互斥访问,在写入的时候不能读取
        g_num++;
        printf("生产者NUM : %d\n",g_num);
        LeaveCriticalSection(&g_thread);
        ReleaseSemaphore(g_Semaphore_full,1,NULL);//信号量++
    }
    return 0;
}

unsigned int __stdcall customer(void *pPM){
    int ok=1;
    while(1){
        WaitForSingleObject(g_Semaphore_full,INFINITE);
        EnterCriticalSection(&g_thread);//对于g_num因为是共享的数据,需要互斥访问,在读取的时候不能被访问
        printf("       消费者NUM : %d\n",g_num);
        LeaveCriticalSection(&g_thread);
        ReleaseSemaphore(g_Semaphore_empty,1,NULL);//信号量++
        if(g_num == 9)ok=0; 
    }
    return 0;

}

int main(){

    InitializeCriticalSection(&g_thread);
    g_Semaphore_full = CreateSemaphore(NULL,0,1,NULL);//当前0个资源,最大允许1个同时访
    g_Semaphore_empty = CreateSemaphore(NULL,0,1,NULL);//当前0个资源,最大允许1个同时访


    HANDLE handle[10];

    ReleaseSemaphore(g_Semaphore_empty,1,NULL);//信号量++

    handle[0] = (HANDLE)_beginthreadex(NULL,0,producer,NULL,0,NULL);
    handle[1] = (HANDLE)_beginthreadex(NULL,0,customer,NULL,0,NULL);

    WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE);

    getchar(); //一定要在这里设置使主线程停止,否则执行到后面的话,子线程就被关闭了

    CloseHandle(handle[0]);
    CloseHandle(handle[1] );
    CloseHandle(g_Semaphore_full);
    CloseHandle(g_Semaphore_empty);
    DeleteCriticalSection(&g_thread);

    
    return 0;
}

 

后面还有坑,继续!!!