Summarize the previous post on csdn.
Cql23
For more information, see the following example.
# Include <iostream>
# Include <windows. h>
Using namespace STD;
Const unsigned int size = 10;
Const unsigned int pcount = 3;
Const unsigned int ccount = 1;
Unsigned int num = 0;
Int I, J;
Handle mutex, fullsem, emptysem;
Critical_section csection;
Void get ()
{
Waitforsingleobject (mutex, null );
// Cout <"consumes a product, total number of products:" <-- num <Endl; // (1)
Printf ("a product has been consumed, total number of products: % d/N", -- num); // (2)
Releasemutex (mutex );
}
Void put ()
{
Waitforsingleobject (mutex, null );
// Cout <"a product is produced, total number of products:" <++ num <Endl; // (1)
Printf ("a product is produced, total number of products: % d/N", ++ num); // (2)
Releasemutex (mutex );
}
DWORD winapi procdure (lpvoid par)
{
While (true)
{
Waitforsingleobject (fullsem, null );
Waitforsingleobject (mutex, null );
Put ();
Sleep (4000 );
Releasemutex (mutex );
Releasesemaphore (emptysem, 1, null );
}
Return 0;
}
DWORD winapi customer (lpvoid par)
{
While (true)
{
Waitforsingleobject (emptysem, null );
Waitforsingleobject (mutex, null );
Get ();
Sleep (4000 );
Releasemutex (mutex );
Releasesemaphore (fullsem, 1, null );
}
Return 0;
}
Void main ()
{
Mutex = createmutex (null, false, null );
Fullsem = createsemaphore (null, size, size, null );
Emptysem = createsemaphore (null, 0, size, null );
Handle thread [pcount + ccount];
Dword id [pcount + ccount];
For (I = 0; I <pcount; ++ I)
{
Thread [I] = createthread (null, 0, procdure, null, 0, & ID [I]);
If (thread [I] = NULL)
{
Return;
}
}
For (I = pcount; I <pcount + ccount; ++ I)
{
Thread [I] = createthread (null, 0, customer, null, 0, & ID [I]);
If (thread [I] = NULL)
{
Return;
}
}
While (! Getchar ())
{}
}
If we use (1) and comment out (2) in the Code, the cout output will be interrupted by another thread when the output is not completely output. For example:
A product is produced. Total number of products: one product is produced, total number of products: one product is consumed, and total number of products: Production
The total number of products: 1212
In this case, how can we prevent the output from being interrupted? After the output is complete, it will be interrupted again. Note (1) and use (2. The conclusion is:
Cout is NOT thread-safe. It is troublesome to synchronize data on its own.
Printf is thread-safe, that is, it handles thread synchronization.
The above example is for Windows. Thanks
Aizibion
It provides almost cross-platform writing (if you rewrite the produce and customer functions, they will be completely cross-platform ):
# Include <iostream>
# Include <windows. h>
# Include <process. h>
Using namespace STD;
# Ifndef wjh_mutex_h
# Define wjh_mutex_h
# Ifdef Win32
# Define wjh_mutex critical_section
# Elif defined _ Linux
# Define wjh_mutex pthread_mutex_t
# Endif
// Synchronize mutex types
Class wjh_cmutex
{
Public:
Wjh_cmutex ()
{
# Ifdef Win32
M_mutex = new critical_section;
Initializecriticalsection (m_mutex );
# Elif defined _ Linux
M_mutex = new pthread_mutex_t;
Pthread_mutex_init (m_mutex, null );
# Endif
}
~ Wjh_cmutex ()
{
# Ifdef Win32
If (! M_mutex)
{
Deletecriticalsection (m_mutex );
If (! M_mutex)
{
Delete m_mutex;
M_mutex = NULL;
}
}
# Elif defined _ Linux
If (! M_mutex)
{
Pthread_mutex_destroy (m_mutex );
If (! M_mutex)
{
Delete m_mutex;
M_mutex = NULL;
}
}
# Endif
}
// Request
Int acquire ()
{
# Ifdef Win32
Entercriticalsection (m_mutex );
# Elif defined _ Linux
Pthread_mutex_lock (m_mutex );
# Endif
Return 0;
}
// Release
Int release ()
{
# Ifdef Win32
Leavecriticalsection (m_mutex );
# Elif defined _ Linux
Pthread_mutex_unlock (m_mutex );
# Endif
Return 0;
}
PRIVATE:
Wjh_mutex * m_mutex;
};
// Synchronous guard type
Class wjh_gurad
{
Public:
Wjh_gurad (wjh_cmutex * _ mutex)
{
If (! _ Mutex)
{
Return;
}
M_mutex = _ mutex;
_ Mutex-> acquire ();
}
~ Wjh_gurad ()
{
If (! M_mutex)
{
Return;
}
M_mutex-> release ();
}
PRIVATE:
Wjh_cmutex * m_mutex;
};
# Endif
Const unsigned int size = 10;
Const unsigned int pcount = 3;
Const unsigned int ccount = 1;
Unsigned int num = 0;
Int I, J;
Handle mutex, fullsem, emptysem;
Critical_section csection;
Wjh_cmutex g_mutex;
Void get ()
{
Wjh_gurad t_guard (& g_mutex );
Cout <"consumed a product" <"Total number of products:" <-- num <Endl;
}
Void put ()
{
Wjh_gurad t_guard (& g_mutex );
Cout <"produce a product" <"Total number of products:" <++ num <Endl;
}
DWORD winapi procdure (lpvoid par)
{
While (true)
{
Waitforsingleobject (fullsem, null );
Waitforsingleobject (mutex, null );
Put ();
Sleep (4000 );
Releasemutex (mutex );
Releasesemaphore (emptysem, 1, null );
}
Return 0;
}
DWORD winapi customer (lpvoid par)
{
While (true)
{
Waitforsingleobject (emptysem, null );
Waitforsingleobject (mutex, null );
Get ();
Sleep (4000 );
Releasemutex (mutex );
Releasesemaphore (fullsem, 1, null );
}
Return 0;
}
Void main ()
{
Mutex = createmutex (null, false, null );
Fullsem = createsemaphore (null, size, size, null );
Emptysem = createsemaphore (null, 0, size, null );
Handle thread [pcount + ccount];
Dword id [pcount + ccount];
For (I = 0; I <pcount; ++ I)
{
Thread [I] = createthread (null, 0, procdure, null, 0, & ID [I]);
If (thread [I] = NULL)
{
Return;
}
}
For (I = pcount; I <pcount + ccount; ++ I)
{
Thread [I] = createthread (null, 0, customer, null, 0, & ID [I]);
If (thread [I] = NULL)
{
Return;
}
}
While (! Getchar ())
{}
}