MFC多线程互锁
CreateEvent跟CreateMutex的比较:
区别1,
CreateEvent跟CreateMutex,你第一个问题关键在于后者内置了一个计数器,比如:假若同一线程连续申请2次互斥量,那么计数器为2,若需要释放互斥量就需要ReleaseMutex()2次,而前者没有。
区别2,
Event是一个线程通知另一个线程用的,是单向的。一方接收,其它方可以发送。一般用在单纯的同步上,就是一个操作要等待另一个操作完成时用的,双方地位并不平等。
Mutex是用于资源控制用的,对于同一个资源,一次只能有一人可以对资源进行访问。双方的地位是平等的。
Mutex比Event复杂一点,可以用Mutex实现Event的功能
区别3,
MUTEX其实是你进临界区之前的
CreateMutex的使用:
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTESlpMutexAttributes, // 指向安全属性的指针
BOOLbInitialOwner, // 初始化互斥对象的所有者
LPCTSTRlpName // 指向互斥对象名的指针
);
5、
A handle to the mutex object indicates success. If the named mutex object existed before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. Otherwise, the caller created the mutex. NULL indicates failure. To get extended error information, call GetLastError.
#include "stdafx.h"
#include "windows.h"
int main(int argc, char* argv[])
{ HANDLE m_hMutex = CreateMutex(NULL,TRUE,"cplusplus_me");
DWORD dwRet = GetLastError();
if (m_hMutex)
{
if (ERROR_ALREADY_EXISTS == dwRet)
{ printf("程序已经在运行中了,程序退出!\n");
CloseHandle(m_hMutex);
return 0;
}
}
else {
printf("创建互斥量错误,程序退出!\n"); CloseHandle(m_hMutex) ;
return 0;
}
while(1)
{ printf("cplusplus_me\n"); }
CloseHandle(m_hMutex);
return 0;
}
搭配使用的WaitForMultipleObjects:
DWORD WINAPI WaitForMultipleObjects(
__in DWORD nCount,
__in const HANDLE* lpHandles,
__in BOOL bWaitAll,
__in DWORD dwMilliseconds
);
The WaitForMultipleObjects function can specify handles of any of the following object types in the lpHandles array:
· Change notification
· Console input
· Event
· Memory resource notification
· Mutex
· Process
· Semaphore
· Thread
· Waitable timer
例子2:(MUTEX对于同一个资源,一次只能有一人可以对资源进行访问)
这个例子使用了 WaitForSingleObject的方法,下面将用WaitForMultipleObjects
#include <iostream>
#include <afx.h>
#include <process.h>
using namespace std;
HANDLE hUp;
CRITICAL_SECTION g_data;
int arr[10];
HANDLE hMutex; //使用手动重置为无信号状态,初始化时有信号状态
UINT __stdcall Add(LPVOID lParam)
{
DWORD dReturn = WaitForSingleObject(hMutex,INFINITE);
for (int i = 0; i<10;i++ )
{
arr[i]=i;//0-9
}
for (int i = 0;i < 10; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
ReleaseMutex(hMutex);
return 1;
}
UINT __stdcall Add2(LPVOID lParam)
{
DWORD dReturn = WaitForSingleObject(hMutex,INFINITE);
for (int i = 0; i<100 ;i++)
{
arr [i] = i+100;//10`1
}
for (int i = 0;i < 10; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
ReleaseMutex(hMutex);
return 1;
}
int main()
{
hMutex = CreateMutex(NULL,FALSE,"");
hUp=(HANDLE)_beginthreadex(NULL, 0, Add, NULL, NULL, 0);
hUp=(HANDLE)_beginthreadex(NULL, 0, Add2, NULL, NULL, 0);
Sleep(5000);
}
例字3:(CreateEvent 一般用在单纯的同步上,就是一个操作要等待另一个操作完成时用的)(330有关)
Waiting for Multiple Objects
The following example uses the CreateEvent function to create two event objects and the CreateThread function to create a thread. It then uses the WaitForMultipleObjects function to wait for the thread to set the state of one of the objects to signaled using the SetEvent function.
For an example that waits for a single object, see Using Mutex Objects.
#include <windows.h>
#include <stdio.h>
HANDLE ghEvents[2];
DWORD WINAPI ThreadProc( LPVOID );
void main()
{
HANDLE hThread;
DWORD i, dwEvent, dwThreadID;
// Create two event objects
for (i = 0; i < 2; i++)
{
ghEvents[i] = CreateEvent(
NULL, // default security attributes
FALSE, // auto-reset event object
FALSE, // initial state is nonsignaled
NULL); // unnamed object
if (ghEvents[i] == NULL)
{
printf("CreateEvent error: %d\n", GetLastError() );
ExitProcess(0);
}
}
// Create a thread
hThread = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) ThreadProc,
NULL, // no thread function arguments
0, // default creation flags
&dwThreadID); // receive thread identifier
if( hThread == NULL )
{
printf("CreateThread error: %d\n", GetLastError());
return;
}
// Wait for the thread to signal one of the event objects
dwEvent = WaitForMultipleObjects(
2, // number of objects in array
ghEvents, // array of objects
FALSE, // wait for any object
5000); // five-second wait
// The return value indicates which event is signaled
switch (dwEvent)
{
// ghEvents[0] was signaled
case WAIT_OBJECT_0 + 0:
// TODO: Perform tasks required by this event
printf("First event was signaled.\n");
break;
// ghEvents[1] was signaled
case WAIT_OBJECT_0 + 1:
// TODO: Perform tasks required by this event
printf("Second event was signaled.\n");
break;
case WAIT_TIMEOUT:
printf("Wait timed out.\n");
break;
// Return value is invalid.
default:
printf("Wait error: %d\n", GetLastError());
ExitProcess(0);
}
// Close event handles
for (i = 0; i < 2; i++)
CloseHandle(ghEvents[i]);
}
DWORD WINAPI ThreadProc( LPVOID lpParam )
{
// Set one event to the signaled state
if ( !SetEvent(ghEvents[0]) ) (330中的使用方法)
{
printf("SetEvent failed (%d)\n", GetLastError());
return -1;
}
return 1;
}
区别1,
CreateEvent跟CreateMutex,你第一个问题关键在于后者内置了一个计数器,比如:假若同一线程连续申请2次互斥量,那么计数器为2,若需要释放互斥量就需要ReleaseMutex()2次,而前者没有。
区别2,
Event是一个线程通知另一个线程用的,是单向的。一方接收,其它方可以发送。一般用在单纯的同步上,就是一个操作要等待另一个操作完成时用的,双方地位并不平等。
Mutex是用于资源控制用的,对于同一个资源,一次只能有一人可以对资源进行访问。双方的地位是平等的。
Mutex比Event复杂一点,可以用Mutex实现Event的功能
区别3,
MUTEX其实是你进临界区之前的
CreateMutex的使用:
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTESlpMutexAttributes, // 指向安全属性的指针
BOOLbInitialOwner, // 初始化互斥对象的所有者
LPCTSTRlpName // 指向互斥对象名的指针
);
5、
A handle to the mutex object indicates success. If the named mutex object existed before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. Otherwise, the caller created the mutex. NULL indicates failure. To get extended error information, call GetLastError.
#include "stdafx.h"
#include "windows.h"
int main(int argc, char* argv[])
{ HANDLE m_hMutex = CreateMutex(NULL,TRUE,"cplusplus_me");
DWORD dwRet = GetLastError();
if (m_hMutex)
{
if (ERROR_ALREADY_EXISTS == dwRet)
{ printf("程序已经在运行中了,程序退出!\n");
CloseHandle(m_hMutex);
return 0;
}
}
else {
printf("创建互斥量错误,程序退出!\n"); CloseHandle(m_hMutex) ;
return 0;
}
while(1)
{ printf("cplusplus_me\n"); }
CloseHandle(m_hMutex);
return 0;
}
搭配使用的WaitForMultipleObjects:
DWORD WINAPI WaitForMultipleObjects(
__in DWORD nCount,
__in const HANDLE* lpHandles,
__in BOOL bWaitAll,
__in DWORD dwMilliseconds
);
The WaitForMultipleObjects function can specify handles of any of the following object types in the lpHandles array:
· Change notification
· Console input
· Event
· Memory resource notification
· Mutex
· Process
· Semaphore
· Thread
· Waitable timer
例子2:(MUTEX对于同一个资源,一次只能有一人可以对资源进行访问)
这个例子使用了 WaitForSingleObject的方法,下面将用WaitForMultipleObjects
#include <iostream>
#include <afx.h>
#include <process.h>
using namespace std;
HANDLE hUp;
CRITICAL_SECTION g_data;
int arr[10];
HANDLE hMutex; //使用手动重置为无信号状态,初始化时有信号状态
UINT __stdcall Add(LPVOID lParam)
{
DWORD dReturn = WaitForSingleObject(hMutex,INFINITE);
for (int i = 0; i<10;i++ )
{
arr[i]=i;//0-9
}
for (int i = 0;i < 10; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
ReleaseMutex(hMutex);
return 1;
}
UINT __stdcall Add2(LPVOID lParam)
{
DWORD dReturn = WaitForSingleObject(hMutex,INFINITE);
for (int i = 0; i<100 ;i++)
{
arr [i] = i+100;//10`1
}
for (int i = 0;i < 10; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
ReleaseMutex(hMutex);
return 1;
}
int main()
{
hMutex = CreateMutex(NULL,FALSE,"");
hUp=(HANDLE)_beginthreadex(NULL, 0, Add, NULL, NULL, 0);
hUp=(HANDLE)_beginthreadex(NULL, 0, Add2, NULL, NULL, 0);
Sleep(5000);
}
例字3:(CreateEvent 一般用在单纯的同步上,就是一个操作要等待另一个操作完成时用的)(330有关)
Waiting for Multiple Objects
The following example uses the CreateEvent function to create two event objects and the CreateThread function to create a thread. It then uses the WaitForMultipleObjects function to wait for the thread to set the state of one of the objects to signaled using the SetEvent function.
For an example that waits for a single object, see Using Mutex Objects.
#include <windows.h>
#include <stdio.h>
HANDLE ghEvents[2];
DWORD WINAPI ThreadProc( LPVOID );
void main()
{
HANDLE hThread;
DWORD i, dwEvent, dwThreadID;
// Create two event objects
for (i = 0; i < 2; i++)
{
ghEvents[i] = CreateEvent(
NULL, // default security attributes
FALSE, // auto-reset event object
FALSE, // initial state is nonsignaled
NULL); // unnamed object
if (ghEvents[i] == NULL)
{
printf("CreateEvent error: %d\n", GetLastError() );
ExitProcess(0);
}
}
// Create a thread
hThread = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) ThreadProc,
NULL, // no thread function arguments
0, // default creation flags
&dwThreadID); // receive thread identifier
if( hThread == NULL )
{
printf("CreateThread error: %d\n", GetLastError());
return;
}
// Wait for the thread to signal one of the event objects
dwEvent = WaitForMultipleObjects(
2, // number of objects in array
ghEvents, // array of objects
FALSE, // wait for any object
5000); // five-second wait
// The return value indicates which event is signaled
switch (dwEvent)
{
// ghEvents[0] was signaled
case WAIT_OBJECT_0 + 0:
// TODO: Perform tasks required by this event
printf("First event was signaled.\n");
break;
// ghEvents[1] was signaled
case WAIT_OBJECT_0 + 1:
// TODO: Perform tasks required by this event
printf("Second event was signaled.\n");
break;
case WAIT_TIMEOUT:
printf("Wait timed out.\n");
break;
// Return value is invalid.
default:
printf("Wait error: %d\n", GetLastError());
ExitProcess(0);
}
// Close event handles
for (i = 0; i < 2; i++)
CloseHandle(ghEvents[i]);
}
DWORD WINAPI ThreadProc( LPVOID lpParam )
{
// Set one event to the signaled state
if ( !SetEvent(ghEvents[0]) ) (330中的使用方法)
{
printf("SetEvent failed (%d)\n", GetLastError());
return -1;
}
return 1;
}