以下以win32平台为例。我们先看一个非多线程的程序:
通过试验,我发现系统(这里是win32)不能将CreateThread()所产生的线程归结到try{}中。更加严重的情况是,即使用一个函数囊括了整个程序,然后try这个函数,其他线程依然脱离了这个try。
所以,一个解决方法是,凡是遇到新的线程,必须在新线程中重新写异常处理。不然,就如google代码标准里所说的那样,不使用C++的异常机制。毕竟C++没有定义多线程的标准,所以也就无从说起多线程中异常处理的标准。
最后附上在新线程写异常处理的参考:
#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 < 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 ;
}
#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 ;
}
很不幸,这个程序编译的时候是可以通过的,但是运行时出错:
#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。
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application ' s support team for more information.
请按任意键继续. . .
通过试验,我发现系统(这里是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 ;
}
#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 ;
}