以下以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 閱讀(2644)
評論(2) 編輯 收藏 引用 所屬分類:
語言基礎、數據結構與算法 、
Win32與VC