异常是否属于C ++中的线程或进程?

时间:2018-11-01 15:05:13

标签: c++ multithreading exception

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

每个线程属于一个异常并且每个线程一次只能有一个异常是否正确?

2 个答案:

答案 0 :(得分:1)

  

是否正确,异常属于每个线程

是的。

  

每个线程一次最多只能有一个异常?

一个线程可以有多个活动异常。参见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

答案 1 :(得分:0)

下面的示例显示异常处理程序正在使用线程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