异常属于C++中的线程还是进程

Does exception belong to threads or process in C++?

本文关键字:进程 线程 属于 C++ 异常      更新时间:2023-10-16

假设我们有两个正在运行的线程,它们都会抛出异常,并且这些线程中有异常处理程序。C++是否能够处理这一问题,而不会遇到终止或未定义的行为。

异常属于每个线程,并且每个线程一次只能有一个异常,这正确吗?

异常属于每线程是否正确

这是正确的。

,并且每个线程一次只能有一个异常?

一个线程可以有多个活动异常。参见int uncaught_exceptions() noexcept:

检测当前线程中有多少异常已抛出或重新抛出,但尚未输入其匹配的catch子句。

例如:

#include <iostream>
#include <stdexcept>
void f() {
throw std::runtime_error("error");
}
struct A {
~A() {
std::cout << "uncaught_exceptions: " << std::uncaught_exceptions() << 'n';
}
};
struct B {
~B() {
try {
A a;
f();
}
catch(std::exception&) {}
}
};
int main() {
try {
B b;
f();
}
catch(std::exception&) {}
}

输出:

uncaught_exceptions: 2

以下示例显示异常处理程序正在使用线程t1的堆栈,该堆栈生成了一个除以零的异常。这意味着异常属于每个线程。

// g++ -std=c++0x -pthread -fnon-call-exceptions main.cpp
#include <iostream>
#include <thread>
#include <signal.h>
void handler(int signo) {
int handler_local_var;
std::cout << &handler_local_var << " in stack of handler" << std::endl;
throw signo;
}
void thread1(std::string msg) {
int t1_local_var;
std::cout << &t1_local_var << " in stack of " << msg << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
signal(SIGFPE,handler);
try { 
int x = 100 / 0; /* ignore warning: division by zero [-Wdiv-by-zero] */
}
catch (...) {
std::cout << "caught" << std::endl;
}
while (1) {
std::this_thread::sleep_for(std::chrono::seconds(2));
}
}
void thread2(std::string msg) {
int t2_local_var;
std::cout << &t2_local_var << " in stack of " << msg <<  std::endl;
while (1) {
std::this_thread::sleep_for(std::chrono::seconds(2));
}
}
int main() {
int main_local_var;
std::cout << &main_local_var << " in stack of main" << std::endl;
std::thread t1(thread1,"t1");
std::thread t2(thread2,"t2");
while (1) {
std::this_thread::sleep_for(std::chrono::seconds(2)); /* Ctrl-C to stop */
}
return 0;
}

测试结果:

$ ./a.out 
0x7ffee7fea788 in stack of main
0x7f0b54b92d68 in stack of t2
0x7f0b55393d54 in stack of t1
0x7f0b55393754 in stack of handler
caught