在多线程中抛出的异常出错?

11 篇文章 0 订阅
以下以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 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值