Относится ли исключение к потокам или процессам в C ++? - PullRequest
0 голосов
/ 01 ноября 2018

Допустим, у нас есть два работающих потока, которые оба будут генерировать исключения, и в этих потоках есть обработчики исключений. Может ли C ++ справиться с этим, не сталкиваясь с завершенным или неопределенным поведением.

Правильно ли, что исключение принадлежит каждому потоку, и каждый поток может иметь не более одного исключения одновременно?

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

В следующем примере показано, что обработчик исключений использует стек потока 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
0 голосов
/ 01 ноября 2018

Правильно ли, что исключение принадлежит каждому потоку

Это правильно.

и каждый поток может иметь не более одного исключения за раз?

Поток может иметь более одного активного исключения. См 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...