随笔 - 96  文章 - 255  trackbacks - 0
<2010年6月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

E-mail:zbln426@163.com QQ:85132383 长期寻找对战略游戏感兴趣的合作伙伴。

常用链接

留言簿(21)

随笔分类

随笔档案

SDL相关网站

我的个人网页

我的小游戏

资源下载

搜索

  •  

积分与排名

  • 积分 - 478007
  • 排名 - 36

最新评论

阅读排行榜

评论排行榜

以下以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 阅读(2535) 评论(2)  编辑 收藏 引用 所属分类: 语言基础、数据结构与算法Win32与VC

FeedBack:
# re: 在多线程中抛出的异常出错? 2014-05-05 22:43 hak1985
其实我就很希望能有这个功能,可以来实现对一个代码段的超时控制;java里是可以这么做的。  回复  更多评论
  
# re: 在多线程中抛出的异常出错? 2014-05-05 22:44 hak1985
其实这个功能很有用,可以实现对一个代码段的超时控制,可惜c++不支持;java好像可以这么做  回复  更多评论
  

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理