以下以win32平台为例。我们先看一个非多线程的程序:
#include <iostream>
#include <windows.h>
DWORD WINAPI thread_func(LPVOID pN)
{
    for (int i = 0; i < *((int*)pN); ++i) {
        std::cout << i+1 << "\t";
    }
    std::cout << std::endl;
    throw "ok.";
    std::cout << "thread_func() done." << std::endl;
    return 0;
}
int main(int argc, char* argv[])
{
    int n = 5;
    try{
    thread_func((LPVOID)&n);
    Sleep(2000);
    }
    catch (const char* s) {
        std::cerr << s << std::endl;
        exit(1);
    }
    std::cout << "main() done." << std::endl;
    return 0;
}
可以看到,函数thread_func()可以正确的抛出异常并被main()的catch捕捉。但是,如果用一个新线程来运行thread_func()会出现什么情况呢?
#include <iostream>
#include <windows.h>
DWORD WINAPI thread_func(LPVOID pN)
{
    for (int i = 0; i < *((int*)pN); ++i) {
        std::cout << i+1 << "\t";
    }
    std::cout << std::endl;
    throw "ok.";
    std::cout << "thread_func() done." << std::endl;
    return 0;
}
int main(int argc, char* argv[])
{
    HANDLE hThrd;
    DWORD thrdId;
    int n = 5;
    try{
    hThrd = CreateThread(    NULL,
                            0,
                            thread_func,
                            (LPVOID)&n,
                            0,
                            &thrdId);
    Sleep(2000);
    }
    catch (const char* s) {
        std::cerr << s << std::endl;
        exit(1);
    }
    std::cout << "main() done." << std::endl;
    return 0;
}
很不幸,这个程序编译的时候是可以通过的,但是运行时出错:
1       2       3       4       5
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
请按任意键继续. . .
而且同时会有一个运行时错误的提示。事实上,这个错误提示意味着程序在没有发现try{}的时候看到了throw。
通过试验,我发现系统(这里是win32)不能将CreateThread()所产生的线程归结到try{}中。更加严重的情况是,即使用一个函数囊括了整个程序,然后try这个函数,其他线程依然脱离了这个try。
所以,一个解决方法是,凡是遇到新的线程,必须在新线程中重新写异常处理。不然,就如google代码标准里所说的那样,不使用C++的异常机制。毕竟C++没有定义多线程的标准,所以也就无从说起多线程中异常处理的标准。
最后附上在新线程写异常处理的参考:
#include <iostream>
#include <windows.h>
DWORD WINAPI thread_func(LPVOID pN)
{
    try{
    for (int i = 0; i < *((int*)pN); ++i) {
        std::cout << i+1 << "\t";
    }
    std::cout << std::endl;
    throw "ok.";
    }
    catch (const char* s) {
        std::cerr << s << std::endl;
        exit(1);
    }
    std::cout << "thread_func() done." << std::endl;
    return 0;
}
int main(int argc, char* argv[])
{
    HANDLE hThrd;
    DWORD thrdId;
    int n = 5;
    hThrd = CreateThread(    NULL,
                            0,
                            thread_func,
                            (LPVOID)&n,
                            0,
                            &thrdId);
    Sleep(2000);
    std::cout << "main() done." << std::endl;
    return 0;
}
	posted on 2010-06-05 20:16 
lf426 阅读(2672) 
评论(2)  编辑 收藏 引用  所属分类: 
语言基础、数据结构与算法 、
Win32与VC