2013-03-03 2 views
4

Хотя этот вопрос не ограничивается библиотеками OpenKinect, это лучший пример, который я мог бы предложить, чтобы показать это.Ловля исключений с Pthreads

В C++ Wrapper для OpenKinect, всякий раз, когда что-то идет не так, он выдает исключение runtime_error. Этот пример приведен из libfreenect.hpp. Нить создается в конструкторе класса.

// Do not call directly, thread runs here 
void operator()() { 
    while(!m_stop) { 
     if(freenect_process_events(m_ctx) < 0) throw std::runtime_error("Cannot process freenect events"); 
    } 
} 

static void *pthread_callback(void *user_data) { 
    Freenect* freenect = static_cast<Freenect*>(user_data); 
    (*freenect)(); 
    return NULL; 
} 

Мой вопрос просто: можно ли как-то поймать эти ошибки и обработать их?

Как правило, я бы справился с исключениями или переписал код: мне не нравится, когда программы сбой из-за исключений, я бы лучше их обработал, если бы знал, что это возможно для них. Есть несколько библиотек, которые делают подобные вещи, которые я не могу переписать, поэтому почему я пришел, чтобы задать этот вопрос.

+0

Почему вы не можете обрабатывать исключения? Почему бы не попробовать/поймать «(* freenect)(); вызов? –

+0

Все дело в том, что это часть библиотеки. Хотя этот является открытым исходным кодом и может быть изменен, есть и другие ситуации, которые я не могу изменить. Поэтому я просто хотел узнать, можно ли бросить вызов из другого потока, используя pthreads. – AdmiralJonB

+1

Не напрямую, нет. Исключения представляют собой механизм, основанный на стеках, и поэтому зависят от потока. Если вы не поймаете их в pthreads, потоки будут закрыты молча. Для передачи исключений из других потоков потребуются межпоточные коммиты в catch {}; –

ответ

0

Вы должны более четко определить, каковы обязанности потока. Я предполагаю, что он передает некоторые сообщения другим потокам через какой-то канал или параллельную очередь. В этом случае просто измените свой класс сообщений для хранения информации об исключении (std :: exception_ptr). Когда вы получаете доступ к данным в сообщении, сначала проверьте, содержит ли оно исключение; Если это так, вызовите std :: rethrow_exception().

Подобный механизм используется в std :: future(); либо вы получаете() обещанное значение, либо возникает исключение при попытке сделать это, исходящее из другого потока. Найдите примеры std :: async(), чтобы увидеть их в действии.

Смежные вопросы