// Producer-consumer is a classic process synchronization problem, which was first proposed by Dijkstra to demonstrate the semaphore mechanism proposed by him. // Two threads executed in the same process address space. The producer thread produces the item and places the item in an empty buffer for consumption by the consumer thread. // The Consumer thread obtains the item from the buffer and then releases the buffer. When the producer thread produces an item, if no empty buffer zone is available, the producer thread must wait for the consumer thread to release an empty buffer zone. // When the consumer thread consumes an item, if the buffer is not full, the consumer thread will be blocked until the new item is produced. Const unsigned short int buffsize = 10; // buffer length unsigned short int in = 0; // the producer's production product enters the buffer subscript unsigned short int out = 0; // consumer obtains the product output buffer subscript unsigned short int nproductid = 0; // production product idunsigned short int nconsumeid = 0; // consumption product idint g_buff [buffsize] = {0 }; // buffer bool g_bcontinue = true; // The control program ends handle g_hmutex = NULL; // The thread synchronization mutex handle g_hproducersemaphore = NULL; // The producer buffer semaphore, waiting for handle g_hcustomersemap when it is full Hore = NULL; // consumer buffer semaphore, waiting for Blank // production product, put into the queue void produce () {handle hproducer = getcurrentthread (); tchar szhandle [100]; _ stscanf (szhandle, _ T ("% d"), hproducer); cout <"the producer is" <szhandle <", new Product ID is "<++ nproductid <", Buffer Index is "<in <Endl; // simplify g_buff [in] = nproductid; in = (in + 1) % buffsize; // Current Status of the output buffer for (INT I = 0; I <buffsize; I ++) {cout <I <":" <g_buff [I]; if (I = In) {cout <"<-- Production" ;}if (I = out) {cout <"<-- consumption" ;}cout <Endl ;}} // producer thread unsigned winapi producethread (lpvoid PARAM) {While (g_bcontinue) {If (wait_object_0! = Waitforsingleobject (g_hproducersemaphore, 30) {continue;} If (wait_object_0! = Waitforsingleobject (g_hmutex, infinite) // get the Buf permission {releasesemaphore (g_hproducersemaphore, 1, null); continue;} produce (); sleep (2000 ); releasemutex (g_hmutex); releasesemaphore (g_hcustomersemaphore, 1, null);} return 0 ;}// obtain from the buffer, consumption product void consume () {nconsumeid = g_buff [out]; handle hcustomer = getcurrentthread (); tchar szhandle [100]; _ stscanf (szhandle, _ T ("% d"), hcustomer ); cout <"--> the customer is" <SZ Handle <", consume product ID is" <nconsumeid <", Buffer Index is" <out <Endl; // simplified processing out = (out + 1) % buffsize; // Current Status of the output buffer for (INT I = 0; I <buffsize; I ++) {cout <I <": "<g_buff [I]; if (I = In) {cout <" <-- production ";} if (I = out) {cout <"<-- consumption" ;}cout <Endl ;}// consumer thread unsigned winapi consumethread (lpvoid PARAM) {While (g_bcontinue) {If (wait_object_0! = Waitforsingleobject (g_hcustomersemaphore, 30) {continue;} If (wait_object_0! = Waitforsingleobject (g_hmutex, infinite) // get the Buf permission {releasesemaphore (g_hcustomersemaphore, 1, null); continue;} consume (); sleep (2000 ); releasemutex (g_hmutex); releasesemaphore (g_hproducersemaphore, 1, null);} return 0;} int _ tmain (INT argc, tchar * argv [], tchar * envp []) {int nretcode = 0; // initialize the MFC and display the error if (! Afxwininit (: getmodulehandle (null), null,: getcommandline (), 0) {// todo: change the error code to meet your needs _ tprintf (_ T ("error: MFC initialization failed \ n"); nretcode = 1;} else {// todo: write code for the behavior of the application here. G_hmutex = createmutex (null, false, null); If (g_hmutex = NULL) {cout <_ T ("create mutex error") <Endl ;} outputs = createsemaphore (null, buffsize, buffsize, null); g_hcustomersemaphore = createsemaphore (null, 0, buffsize, null); If (g_hproducersemaphore = NULL | returns = NULL) {cout <_ T ("create semaphore error") <Endl ;}// defines the number of producer and consumer threads int I = 0; const int nproducerthreadnum = 3; const int ncustomerthreadnum = 1; handle haproducer [nproducerthreadnum]; handle hacustomer [ncustomerthreadnum]; handle htmp = NULL; for (I = 0; I <nproducerthreadnum; I ++) {haproducer [I] = createthread (null, 0, (lpthread_start_routine) producethread, null, 0, null) ;}for (I = 0; I <ncustomerthreadnum; I ++) {hacustomer [I] = createthread (null, 0, (lpthread_start_routine) consumethread, null, 0, null);} If (getchar ()) {// any key to exit g_bcontinue = false;} DWORD dwwaitproducer = exist (nproducerthreadnum, (const handle *) haproducer, true, infinite); DWORD dwwaitcustomer = waitformultipleobjects (ncustomerthreadnum, (const handle *) hacustomer, true, infinite); for (I = 0; I <nproducerthreadnum; I ++) {closehandle (haproducer [I]);} for (I = 0; I <ncustomerthreadnum; I ++) {closehandle (hacustomer [I]);} closehandle (g_hmutex); closehandle (g_hproducersemaphore); closehandle (handler );} return nretcode ;}