?? win32 multithreading and synchronization.html
字號:
<div class="center">
<pre class="example">
DWORD WaitForMultipleObjects(
DWORD nCount, // number of handles in array
CONST HANDLE *lpHandles, // object-handle array
BOOL bWaitAll, // wait option
DWORD dwMilliseconds // time-out interval
);
</pre>
</div>
<p>
If the third parameter is set to TRUE, the function will wait for all of the objects to become available. If the third parameter is set to FALSE, the function will wait for any of the objects to become available, the return value of the function will be the index to the handles array to let you know which object that has been obtained.
</p>
<p class="para">
<span class="function">WaitForMultipleObjectsEx</span> is the same as <span class="function">WaitForSingleObjectEx</span>, except it allows you to wait for multiple objects.
</p>
<div class="center">
<pre class="example">
DWORD WaitForMultipleObjectsEx(
DWORD nCount, // number of handles in array
CONST HANDLE *lpHandles, // object-handle array
BOOL bWaitAll, // wait option
DWORD dwMilliseconds, // time-out interval
BOOL bAlertable // alertable option
);
</pre>
</div>
<a name="mutex">
<h3>Mutexes:</h3>
<p class="para">
Like all other synchronization objects, a mutex is created by the Windows Object Manager. Mutex is short for mutual exclusion, meaning that only one thread can own it at a time. Think of it as a sort of ticket, any thread holding the ticket gets to access whatever is being protected by the mutex. While the thread is doing its job, all the other threads wait. Once the thread is done, it gives the ticket away and the next thread can do what it needs to do while the other threads wait.
</p>
<p class="para">
To create a mutex call <span class="function">CreateMutex</span>:
</p>
<div class="center">
<pre class="example">
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes,
BOOL bInitialOwner, // initial owner
LPCTSTR lpName // object's name
);
</pre>
</div>
<p>
The first parameter can be passed as NULL to obtain the default access rights. If the second parameter is set to TRUE, the creator of the mutex will have ownership first. The third parameter is optional, it can be used to easily identify the mutex.
</p>
<p class="para">
To release the mutex after doing whatever needs to be done, call <span class="function">ReleaseMutex</span>.
</p>
<div class="center">
<pre class="example">
BOOL ReleaseMutex(
HANDLE hMutex // handle to mutex
);
</pre>
</div>
<p>
Only the thread that owns the mutex can release it. To destroy the mutex, call <span class="function">CloseHandle</span> with the handle to the mutex.
</p>
</div>
<a name="sema">
<h3>Semaphores:</h3>
<p class="para">
A semaphore is useful when you want to only allow a limited amount of threads to access a protected resource at a time. With a mutex, only one thread can own it at any given moment. With a semaphore, multiple threads can own it at a time. Consequently, any thread can also destroy the semaphore. To create a semaphore call <span class="function">CreateSemaphore</span>.
</p>
<div class="center">
<pre class="example">
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
LONG lInitialCount, // initial count
LONG lMaximumCount, // maximum count
LPCTSTR lpName // object's name
);
</pre>
</div>
<p>
The first parameter is handled the exact same as the first parameter of <span class="function">CreateMutex</span>. The second parameter sets the initial count of the semaphore, usually it's set to the same value as that of the maximum count. The initial count cannot be less than zero nor greater than the maximum count. The third parameter sets the maximum count which limits the number of threads that can own the semaphore. The last parameter is handled the same way as that of <span class="function">CreateMutex</span>. After a thread gains possession of the semaphore the initial count is decremented one. If the initial count reaches 0, no more threads can gain possession of the semaphore. The initial count is incremented after a thread releases the semaphore.
</p>
<p class="para">
To release a semaphore, call <span class="function">ReleaseSemaphore</span>.
</p>
<div class="center">
<pre class="example">
BOOL ReleaseSemaphore(
HANDLE hSemaphore, // handle to semaphore
LONG lReleaseCount, // count increment amount
LPLONG lpPreviousCount // previous count
);
</pre>
</div>
<p>
The second parameter sets by how much the count should be incremented, usually this is 1. The third parameter holds a pointer to a variable that will be filled with the previous count, after <span class="function">ReleaseSemaphore</span> completes.
</p>
<a name="cs">
<h3>Critical Sections:</h3>
<p class="para">
A critical section is very similar to a mutex. A critical section can only be owned by one thread at a time, however, a critical section cannot be shared between processes, a mutex can. Because of this, a critical section works more quickly. To create a critical section, call <span class="function">InitializeCriticalSection</span>; to own a critical section, call <span class="function">EnterCriticalSection</span>; to give up ownership of a critical section, call <span class="function">LeaveCriticalSection</span>; to destroy a critical section, call <span class="function">DeleteCriticalSection</span>.
</p>
<div class="center">
<pre class="example">
VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
</pre>
</div>
<div class="center">
<pre class="example">
VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
</pre>
</div>
<div class="center">
<pre class="example">
VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
</pre>
</div>
<div class="center">
<pre class="example">
VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
</pre>
</div>
<p>
All of the functions require a pointer to the critical section object. You declare one like this:
</p>
<div class="center">
<pre class="example">
CRITICAL_SECTION cs;
</pre>
</div>
<p class="para">
Any thread that is of the process that created the critical section can destroy the critical section.
</p>
<a name="events">
<h3>Events:</h3>
<p class="para">
An event object is useful when you want to alert threads of an action occurring, a button being pushed for example. An event object is sent to all waiting threads. Call <span class="function">CreateEvent</span> to create an event; call <span class="function">SetEvent</span> to signal an event; call <span class="function">ResetEvent</span> to turn the signal off. When an event is signaled, all threads that wait for it will receive it; when the event is not signaled, the threads will wait. You can also call <span class="function">PulseEvent</span> to quickly signal and unsignal an event. This is useful in releasing the waiting threads.
</p>
<p class="para">
<span class="function">CreateEvent</span> takes the following parameters:
</p>
<div class="center">
<pre class="example">
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset, // reset type
BOOL bInitialState, // initial state
LPCTSTR lpName // object name
);
</pre>
</div>
<p>
If the second parameter is set to TRUE, the event must be reset manually. If the second parameter is set to FALSE, the event will return to its unsignaled state immediately after a call to <span class="function">SetEvent</span>. If the third parameter is set to TRUE, the event will be created and set to the signaled state. The last parameter is an optional name for the object.
</p>
<p class="para">
<span class="function">SetEvent</span>, <span class="function">ResetEvent</span>, and <span class="function">PulseEvent</span> are all called in the same way:
</p>
<div class="center">
<pre class="example">
BOOL SetEvent(HANDLE hEvent);
</pre>
</div>
<div class="center">
<pre class="example">
BOOL ResetEvent(HANDLE hEvent);
</pre>
</div>
<div class="center">
<pre class="example">
BOOL PulseEvent(HANDLE hEvent);
</pre>
</div>
<p>
hEvent being the handle returned from <span class="function">CreateEvent</span>.
</p>
<p class="para">
The combination of a mutex and an event is a good way to avoid deadlocks. The following is an example of using the mutex and event synchronization objects.
</p>
<div class="center">
<pre class="example">
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
HANDLE hMutex, hWriteDone, hReadDone;
int num, state;
void Writer()
{
for(int x=10; x>=0; x--)
{
while (true)
{
if (WaitForSingleObject(hMutex, INFINITE) == WAIT_FAILED)
{
std::cout<<"In writing loop, no mutex!\n";
ExitThread(0);
}
if (state == 0)
{
ReleaseMutex(hMutex);
WaitForSingleObject(hReadDone, INFINITE);
continue;
}
break;
}
std::cout<<"Write done\n";
num= x;
state= 0;
ReleaseMutex(hMutex);
PulseEvent(hWriteDone);
}
}
void Reader()
{
while(true)
{
if (WaitForSingleObject(hMutex, INFINITE) == WAIT_FAILED)
{
std::cout<<"In reader, no mutex!\n";
ExitThread(0);
}
if (state == 1)
{
ReleaseMutex(hMutex);
WaitForSingleObject(hWriteDone, INFINITE);
continue;
}
if (num == 0)
{
std::cout<<"End of data\n";
ReleaseMutex(hMutex);
ExitThread(0);
}
else {
std::cout<<"Read done\n";
state=1;
ReleaseMutex(hMutex);
PulseEvent(hReadDone);
}
}
}
void main()
{
HANDLE TName[2];
DWORD ThreadID;
state= 1;
hMutex= CreateMutex(NULL, FALSE, NULL);
hWriteDone= CreateEvent(NULL, TRUE, FALSE, NULL);
hReadDone= CreateEvent(NULL, TRUE, FALSE, NULL);
TName[0]= CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)Writer,
NULL, 0, &ThreadID);
TName[1]= CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)Reader,
NULL, 0, &ThreadID);
WaitForMultipleObjects(2, TName, TRUE, INFINITE);
CloseHandle(TName);
}
</pre>
</div>
<a name="ref">
<h2>References:</h2>
<ul>
<li><a href="http://msdn.microsoft.com" target="_blank" title="Link opens in a new browser window.">Microsoft Developer Network</a></li>
<li><u>Windows 98 Developer's Handbook</u> by Ben Ezzell and Jim Blaney, Sybex Publishing</li>
</ul>
<a name="con">
<h2>Conclusion:</h2>
<p class="para">
And so ends yet another text file. As always, if you find any errors or have any comments please send them to <a href="mailto:spiderman@witty.com" title="Click to e-mail me.">spiderman@witty.com</a>. Please direct all questions to the message board. Until next time...
</p>
<div class="lastupdate">Last updated: <strong>1/22/01</strong></div>
</body>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -