zoukankan      html  css  js  c++  java
  • MTVERIFY

    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[256];
    #ifdef _WINDOWS_
    TCHAR modulename[MAX_PATH];
    #else
    DWORD numread;
    #endif
    FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    NULL,
    errnum,
    LANG_NEUTRAL,
    (LPTSTR)&lpBuffer,
    0,
    NULL
    );
    wsprintf(errbuf, " The following call failed at line %d in %s: %s Reason: %s ", 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[ Thread_Max_Number ];
    DWORD rc;
    int slot;
    for( int i = 0; i != 10; ++i )
    {
    if( i < 3 )
    {
    MTVERIFY( ThreadH[ i ] = 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[ slot ] ) );
    MTVERIFY( ThreadH[ slot ] = 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[i] );
    }
    for( size_t i = 0; i != number.Vec.size(); ++i )
    cout<<number.Vec[i]<<" ";
    cout<<endl;
    return EXIT_SUCCESS;
    }
  • 相关阅读:
    百度语音
    前端技术
    自动化测试
    分布式锁
    缓存穿透、缓存击穿、缓存雪崩
    延迟队列
    Arthas
    MyBatis配置文件容易引发的不容易发现的问题(驼峰式命名)
    JUnit使用中遇到的问题
    使用ArrayList<E>遇到的数据重复问题
  • 原文地址:https://www.cnblogs.com/azbane/p/7550800.html
Copyright © 2011-2022 走看看