MTVERIFY

#defin #defin #defin

MTVERIFY宏即適用於GUI程式也適用於console程式,這個宏內部其實是記錄並解釋了Win32 GetLastError()的結果。如果Win32函式失敗,MTVERIFY()會列印出一段簡短的文字說明,在多執行緒編程時檢查錯誤效果尤為突出,現在我寫在這裡,供大家參考
使用時注意在頭檔案中加入:#include <MtVerify.h>
然後在程式中用MTVERIFY()括弧括住關於執行緒句柄的代碼,這樣執行緒出了問題,錯誤就會有MTVERIFY負責顯示。
#pragma comment( lib, "USER32" )
#include <crtdbg.h>
#ifdef DEBUG
#define MTASSERT(a) _ASSERTE(a)
#define MTVERIFY(a) if (!(a)) PrintError(#a,__FILE__,__LINE__,GetLastError())
#else
#define MTASSERT(a) (a)
#define MTVERIFY(a) (a)
#endif
__inline void PrintError(LPTSTR linedesc, LPTSTR filename, int lineno, DWORD errnum)
{
LPTSTR lpBuffer;
TCHAR errbuf&#91;256&#93;;
#ifdef _WINDOWS_
TCHAR modulename&#91;MAX_PATH&#93;;
#else
DWORD numread;
#endif
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
errnum,
LANG_NEUTRAL,
(LPTSTR)&lpBuffer,
0,
NULL
);
wsprintf(errbuf, "\nThe following call failed at line %d in %s:\n\n %s\n\nReason: %s\n", lineno, filename, linedesc, lpBuffer);
#ifndef _WINDOWS_
WriteFile(GetStdHandle(STD_ERROR_HANDLE), errbuf, strlen(errbuf), &numread, FALSE );
Sleep(3000);
#else
GetModuleFileName(NULL, modulename, MAX_PATH);
MessageBox(NULL, errbuf, modulename, MB_ICONWARNING|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
#endif
LocalFree(lpBuffer);
exit(EXIT_FAILURE);
}
——源自《win32 多執行緒程式設計》
/***********************************************************************************************/
在後面的編程練習中我發現這個宏的使用會使多執行緒編程的錯誤檢測變得非常簡單,我這裡舉個例子,這個宏的簡單實用方式,是用的後面文章中的一個例子:
#include <iostream>
#include <windows.h>
#include <vector>
#include "MtVerify.h" //自己拷貝這個頭檔案到你的工程
using namespace std;
class Number
{
public:
Number(){ hMutex = CreateMutex( NULL,false, "BruceLee"); }
vector< int > Vec;
void AddItem( const int& n );
~Number(){ CloseHandle( hMutex ); }
private:
HANDLE hMutex;
};
void Number::AddItem( const int & n )
{
WaitForSingleObject( hMutex,INFINITE );
Vec.push_back( n );
ReleaseMutex( hMutex );
}
const int Thread_Max_Number = 3;
Number number;
DWORD WINAPI ThreadFunc( LPVOID n )
{
number.AddItem( int(n) );
return ( (DWORD)n );
}
int main()
{
DWORD ThreadId;
HANDLE ThreadH&#91; Thread_Max_Number &#93;;
DWORD rc;
int slot;
for( int i = 0; i != 10; ++i )
{
if( i < 3 )
{
MTVERIFY( ThreadH&#91; i &#93; = CreateThread( 0,0,ThreadFunc,( LPVOID )i, 0, &ThreadId ) );
}
else
{
rc = WaitForMultipleObjects( Thread_Max_Number, ThreadH, false, INFINITE );
slot = rc - WAIT_OBJECT_0;
MTVERIFY( slot >= 0 && slot < Thread_Max_Number );
cout<<slot<<" has temenated"<<endl;
MTVERIFY( CloseHandle( ThreadH&#91; slot &#93; ) );
MTVERIFY( ThreadH&#91; slot &#93; = CreateThread( 0,0,ThreadFunc,( LPVOID )i, 0, &ThreadId ) );
}
}
MTVERIFY( WaitForMultipleObjects( Thread_Max_Number, ThreadH, true, INFINITE ) );
for( int i = 0; i != Thread_Max_Number; ++i )
{
CloseHandle( ThreadH&#91;i&#93; );
}
for( size_t i = 0; i != number.Vec.size(); ++i )
cout<<number.Vec&#91;i&#93;<<" ";
cout<<endl;
return EXIT_SUCCESS;
}

相關搜尋

熱門詞條

聯絡我們