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, "\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[ 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;
}

MTVERIFY的更多相关文章

  1. win32多线程-新版本MtVerify.h

    api调用错误诊断宏,对GetLastError()函数的封装,并解析错误 从网上找的版本并进行了部分修改 /* * MtVerify.h * * The function PrintError() ...

  2. 使用 MtVerify.h头文件 ,用的时候把他头文件的内容添加到项目

    #include <windows.h>  //windodws变量相关头文件 MtVerify.h的内容如下:#pragma comment( lib, "USER32&quo ...

  3. win32多线程-异步过程调用(asynchronous Procedure Calls, APCs)

    使用overlapped I/O并搭配event对象-----win32多线程-异步(asynchronous) I/O事例,会产生两个基础性问题. 第一个问题是,使用WaitForMultipleO ...

  4. 第6章 Overlapped I/O, 在你身后变戏法 ---被激发的 Event 对象 -4

    以文件 handle 作为激发机制,有一个明显的限制,那就是没办法说出到底是哪一个 overlapped 操作完成了.如果每个文件 handle 只有一个操作等待决定,上述问题其实并不成为问题.但是如 ...

  5. 第5章 不要让线程成为脱缰的野马(Keeping your Threads on Leash) ---干净的终止一个线程

    干净的终止一个线程  我曾经在第2章产生一个后台线程,用以输出一张屏幕外的 bitmap 图.我们必须解决的一个最复杂的问题就是,如果用户企图结束程序,而这张bitmap 图尚未完成,怎么办?第2章的 ...

  6. C++互斥器:Mutex

    互斥器的功能是,使多个线程和谐工作.同一时间内,只能有一个线程得到互斥对象,并获得资源操作权限,那么如果同一时间其他线程也想去操作资源,此时就会因为Mutex未处于激发状态,而无奈的等待…这时候,线程 ...

  7. win32多线程-异步(asynchronous) I/O

    I/O设备是个慢速设备,无论打印机.调制解调器,甚至硬盘,与CPU相比都奇慢无比,坐下来干等I/O的完成是一件不甚明智事情. 异步(asynchronous) I/O在win32多线程程序设计中被称为 ...

  8. 串口通讯编程一日通2(Overlapped IO模型)

    第一篇初步了解串口的大致运作,接下来我们看基本操作 先看串口操作的数据结构: 串口操作有几个比较重要的Struct 1.Overlapped I/O 异步I/O模型 异步I/O和同步I/O不同,同步I ...

  9. Overlapped I/O模型深入分析(转)

    随笔 - 262  文章 - 0  评论 - 531  博客园  首页  新随笔  联系  管理  订阅  Overlapped I/O模型深入分析(转) 简述:    Overlapped I/O也 ...

随机推荐

  1. anaconda安装加速镜像问题解决

    Anaconda使用conda连接网络出现错误 我使用的是windows10 64bit下的Anaconda2,在安装和更新包的时候出现以下报错信息. 这是使用默认源安装包的报错信息: C:Users ...

  2. [js高手之路]设计模式系列课程-委托模式实战微博发布功能

    在实际开发中,经常需要为Dom元素绑定事件,如果页面上有4个li元素,点击对应的li,弹出对应的li内容,怎么做呢?是不是很简单? 大多数人的做法都是:获取元素,绑定事件 <ul> < ...

  3. 谈谈分布式版本管理工具Git

    一.主流的版本管理工具 目前在企业中比较主流的版本管理工具有:GIT.SVN.CVS等等. 二.什么是Git? Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.是 L ...

  4. final关键字的使用

    public class FinalDome extends Final{ private final double PI = 3.1415926;//常量,不可改变 private int num ...

  5. 面向对象五大原则(SRP、OCP、LSP、DIP、ISP)

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt173 OO的五大原则是指 1. SRP(Single Responsibil ...

  6. C++IO类&文件输入输出

    C++IO类&文件输入输出 istream(输入流)类型,提供输入操作. ostream(输出流)类型,提供输出操作. cin,一个istream对象,从标准输入读取数据. cout,一个os ...

  7. poj 1742 多重背包

    题意:给出n种面值的硬币, 和这些硬币每一种的数量, 要求求出能组成的钱数(小于等于m) 思路:一开始直接用多重背包套上去超时了,然后就没辙了,然后参考网上的,说只需要判断是否能取到就行了,并不需要记 ...

  8. tkinter第一章

    tk1 ------------------------------------------------------------------------------------------ impor ...

  9. 团队作业4——第一次项目冲刺(Alpha版本)4.26

    一.当天站立式会议照片 本次会议主要内容:汇报工作进度,根据完成情况调整进度,分配各自接口编写任务. 二.每个人的工作 三.燃尽图 横坐标:工作日,以天为单位,一共七天,代表着Alpha冲刺阶段的时间 ...

  10. 【Beta】阶段 第五次Daily Scrum Meeting

    每日任务 1.本次会议为第五次 Meeting会议: 2.本次会议在周五下午15:35,在禹洲楼召开,召开本次会议为10分钟. 一.今日站立式会议照片 二.每个人的工作 (有work item 的ID ...