Windows Thread (producer and consumer problems) reprinted by qiqiang 2008.10.10
The producer-consumer problem is a classic process synchronization problem 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.
- # Include <windows. h>
- # Include <iostream>
- Const unsigned short size_of_buffer = 10; // buffer Length
- Unsigned short productid = 0; // Product NO.
- Unsigned short consumeid = 0; // product number to be consumed
- Unsigned short in = 0; // buffer subscript when the product enters the Buffer Zone
- Unsigned short out = 0; // buffer subscript when the product outputs the Buffer Zone
- Int g_buffer [size_of_buffer]; // the buffer is a cyclic queue.
- Bool g_continue = true; // The control program ends.
- Handle g_hmutex; // used for mutual exclusion between threads
- Handle g_hfullsemaphore; // forces the producer to wait when the buffer is full.
- Handle g_hemptysemaphore; // force the consumer to wait when the buffer zone is empty
- DWORD winapi producer (lpvoid); // producer thread
- DWORD winapi consumer (lpvoid); // consumer thread
- Int main ()
- {
- // Create mutually exclusive Signals
- G_hmutex = createmutex (null, false, null );
- G_hfullsemaphore = createsemaphore (null, SIZE_OF_BUFFER-1, SIZE_OF_BUFFER-1, null );
- G_hemptysemaphore = createsemaphore (null, 0, SIZE_OF_BUFFER-1, null );
- // Adjust the values below to find that when the number of producers is greater than the number of consumers,
- // The production speed is fast, and the producer often waits for the consumer. On the contrary, the consumer often waits
- Const unsigned short producers_count = 3; // number of producers
- Const unsigned short consumers_count = 1; // number of consumers
- // Total number of threads
- Const unsigned short threads_count = producers_count + consumers_count;
- Handle hthreads [producers_count]; // handle of each thread
- DWORD producerid [consumers_count]; // producer thread identifier
- DWORD consumerid [threads_count]; // consumer thread ID
- // Create a producer thread
- For (INT I = 0; I <producers_count; ++ I ){
- Hthreads [I] = createthread (null, 0, producer, null, 0, & producerid [I]);
- If (hthreads [I] = NULL) Return-1;
- }
- // Create a consumer thread
- For (INT I = 0; I <consumers_count; ++ I ){
- Hthreads [producers_count + I] = createthread (null, 0, consumer, null, 0, & consumerid [I]);
- If (hthreads [I] = NULL) Return-1;
- }
- While (g_continue ){
- If (getchar () {// press enter to terminate the program running
- G_continue = false;
- }
- }
- Return 0;
- }
- // Produce a product. After a simple simulation, only the ID number of the new product is output.
- Void produce ()
- {
- STD: cerr <"producing" <++ productid <"...";
- STD: cerr <"succeed" <STD: Endl;
- }
- // Add the newly produced product to the buffer zone
- Void append ()
- {
- STD: cerr <"appending a product ...";
- G_buffer [in] = productid;
- In = (in + 1) % size_of_buffer;
- STD: cerr <"succeed" <STD: Endl;
- // Output the current status of the buffer
- For (INT I = 0; I <size_of_buffer; ++ I ){
- STD: cout <I <":" <g_buffer [I];
- If (I = In) STD: cout <"<-- production ";
- If (I = out) STD: cout <"<-- consume ";
- STD: cout <STD: Endl;
- }
- }
- // Extract a product from the buffer
- Void take ()
- {
- STD: cerr <"taking a product ...";
- Consumeid = g_buffer [out];
- Out = (out + 1) % size_of_buffer;
- STD: cerr <"succeed" <STD: Endl;
- // Output the current status of the buffer
- For (INT I = 0; I <size_of_buffer; ++ I ){
- STD: cout <I <":" <g_buffer [I];
- If (I = In) STD: cout <"<-- production ";
- If (I = out) STD: cout <"<-- consume ";
- STD: cout <STD: Endl;
- }
- }
- // Consume one product
- Void consume ()
- {
- STD: cerr <"consuming" <consumeid <"...";
- STD: cerr <"succeed" <STD: Endl;
- }
- // Producer
- DWORD winapi producer (lpvoid lppara)
- {
- While (g_continue ){
- Waitforsingleobject (g_hfullsemaphore, infinite );
- Waitforsingleobject (g_hmutex, infinite );
- Produce ();
- Append ();
- Sleep (1500 );
- Releasemutex (g_hmutex );
- Releasesemaphore (g_hemptysemaphore, 1, null );
- }
- Return 0;
- }
- // Consumer
- DWORD winapi consumer (lpvoid lppara)
- {
- While (g_continue ){
- Waitforsingleobject (g_hemptysemaphore, infinite );
- Waitforsingleobject (g_hmutex, infinite );
- Take ();
- Consume ();
- Sleep (1500 );
- Releasemutex (g_hmutex );
- Releasesemaphore (g_hfullsemaphore, 1, null );
- }
- Return 0;
- }