Solution to producer-consumer problems in Windows

Source: Internet
Author: User

First, describe the problem to be solved:

There is a warehouse with a maximum of seven slots. At first, each slot is empty. When there is an empty slot, the producer is allowed to put things in it. When there is something in the slot, the consumer is allowed to take it from it; when it is full, it is not allowed to put it again; if it is empty, it is not allowed to take it again. Because of warehouse design problems, only one person is allowed to put or take things at the same time. It is necessary to arrange the work of producers and consumers as much as possible. We can see that the production and consumption actions do not need to be strictly synchronized here. As long as the rules permit, they can be generated three times in a row or consumed three times in a row. Not to mention the order in which the product must be produced once, consumed once, reproduced once, and consumed again.

 

// Productor_consumer.cpp
// Solution for producer-consumer problems on Windows

# Include <windows. h>
# Include <tchar. h>
# Include <list>

// Define the maximum slot of the Repository
# Define wh_slot 7

// Defines the timeout time for the waiting signal.
# Define timeout 3000

// define the repository class
class warehource
{< br> Public:
warehource ()
{< br> // create a mutex for warehouse access. Producers and consumers cannot access the warehouse at the same time.
m_haccess = createevent (null, false, true, null );
}< br> ~ Warehource ()
{< br> // disable access mutex
closehandle (m_haccess);
}

// Put it in the warehouse
Bool put (char ch)
{
// Try to obtain the mutex
If (wait_object_0 = waitforsingleobject (m_haccess, 100 ))
{
M_slot.push_back (CH );
Printf ("product an item, now warehourse size is % d \ n", m_slot.size ());
Setevent (m_haccess); // Let's next access available
Return true;
}
Return false;
}

// Retrieve from Warehouse
Bool get (char * Ch)
{
// Try to obtain the mutex
If (wait_object_0 = waitforsingleobject (m_haccess, 100 ))
{
* Ch = m_slot.front ();
M_slot.pop_front ();
Printf ("consume an item, now warehourse size is % d \ n", m_slot.size ());
Setevent (m_haccess); // Let's next access available
Return true;
}
Return false;
}
PRIVATE:
STD: List <char> m_slot;
Handle m_haccess; // mutually exclusive access to the repository
};

DWORD winapi productorrun (lpvoid ud );
DWORD winapi consumerrun (lpvoid ud );

Handle g_hprodexit; // producer exit Signal
Handle g_hfreesemaphore; // the signal light of the warehouse's idle slot. The maximum value is wh_slot.

Handle g_hconsexit; // consumer exit Signal
Handle g_hdatasemaphore; // the signal light of the available slot in the warehouse. The maximum value is wh_slot.

Int _ tmain (INT argc, _ tchar * argv [])
{
Warehource Wh;
G_hprodexit = createevent (null, false, false, null );
G_hconsexit = createevent (null, false, false, null );
// The signal of the warehouse idle slot. The maximum value is wh_slot and the initial value is wh_slot.
// It is empty at the beginning.
G_hfreesemaphore = createsemaphore (null, wh_slot, wh_slot, null );
// The signal lights of available slots in the warehouse. The maximum value is wh_slot and the initial value is 0, because the warehouse
// It is empty at the beginning.
G_hdatasemaphore = createsemaphore (null, 0, wh_slot, null );

// Create producer and consumer
Handle hproductor = createthread (null, null, productorrun, & Wh, 0, 0 );
Handle hconsumer = createthread (null, null, consumerrun, & Wh, 0, 0 );

// Let main thread sleep 30 seconds
Sleep (3000 );

// End the producer
Setevent (g_hprodexit );
Waitforsingleobject (hproductor, infinite );
Closehandle (g_hprodexit );
Closehandle (hproductor );

// End consumer
Setevent (g_hconsexit );
Waitforsingleobject (hconsumer, infinite );
Closehandle (g_hconsexit );
Closehandle (hconsumer );
// Turn off the signal light
Closehandle (g_hfreesemaphore );
Closehandle (g_hdatasemaphore );
Return 0;
}

DWORD winapi productorrun (lpvoid ud)
{
Bool fdone = false;
Handle H2 [] = {g_hprodexit, g_hfreesemaphore };
DWORD dwwait = 0;

Warehource * wh = (warehource *) UD;
While (! Fdone)
{
// Wait for the exit signal or idle Signal
Dwwait = waitformultipleobjects (2, H2, false, timeout );
If (dwwait = wait_object_0)
{
// Exit Signal
Fdone = true;
}
Else if (dwwait = wait_object_0 + 1)
{
// Idle signal, indicating there is idle slot in the warehouse and try to put it in the warehouse
If (Wh-> put ('A '))
{
// If one has been successfully placed in the warehouse, set the signal light of the available slot
Releasesemaphore (g_hdatasemaphore, 1, null );
}
Else // warehouse access timeout
{
// Set the idle slot signal to go back.
Releasesemaphore (g_hfreesemaphore, 1, null );
}
}
}

Return 0;
}

DWORD winapi consumerrun (lpvoid ud)
{
Bool fdone = false;
Handle H2 [] = {g_hconsexit, g_hdatasemaphore };
DWORD dwwait = 0;

Warehource * wh = (warehource *) UD;
While (! Fdone)
{
// Wait for the exit signal or available signal
Dwwait = waitformultipleobjects (2, H2, false, timeout );
If (dwwait = wait_object_0)
{
// Exit Signal
Fdone = true;
}
Else if (dwwait = wait_object_0 + 1)
{
// Available signal, indicating the existing data in a slot in the warehouse.
Char ch;
If (Wh-> get (& Ch ))
{
// If one has been successfully retrieved from the warehouse, the signal is set to the idle slot.
Releasesemaphore (g_hfreesemaphore, 1, null );
}
Else // warehouse access timeout
{
// Set the unavailable slot signal to the back
Releasesemaphore (g_hdatasemaphore, 1, null );
}
}
}
Return 0;
}

 

Note that semaphore is the only signal type that allows multiple threads to simultaneously access shared resources.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.