如何从线程程序中的子函数传播异常?

问题描述 投票:0回答:1

我试图了解异常如何在不同函数之间传播并返回到 C++ 中的主函数。我有一个小设置:

main.cpp:

int run () {
.
.
try {
  testException(file);
} catch (const std::exception &e) {
    std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}

测试.cpp

std::exception_ptr g_exceptionPtr = nullptr;

void testThread() {
   std::this_thread::sleep_for(std::chrono::milliseconds(100));
   .
   .
}

void testException(const std::string &file) {
  TestCSV csv(file);
  try {
    std::thread input(testThread);
    csv.writeToCSV(file, a, b, c);
    input.join();
  } catch (const std::runtime_error &e) {
      g_exceptionPtr = std::current_exception();
      std::rethrow_exception(g_exceptionPtr);
  }
}

test_csv.cpp

TestCSV::writeToCSV(const std::string &file, const std::string &a, const std::string &b, const std::string &c) {
.
.
std::ofstream outFile(file);
    if (!outFile.is_open()) {
      throw std::runtime_error("Unable to open file for writing.");
    }
}

现在我想传播来自

writeToCSV
函数的错误并在
main.cpp
中处理它。但是,目前,此异常已在
test.cpp
中捕获,但不会重新抛出到
main.cpp

问题是什么以及如何解决?

P.S:以上代码只是一个示例,如果缺少任何信息,请告诉我

c++ c++11 exception
1个回答
0
投票

您在运行

writeToCSV()
的主线程上下文中调用
main()
,因此
writeToCSV()
引发且未被捕获的任何异常都将传播到
main()
。您不需要为此做任何额外的事情。而你的
std::thread
用法与此无关。

但是,由于您的问题是关于跨线程传播异常,因此您应该更改测试以将

writeToCSV()
移至
std::thread

std::current_exception
允许您捕获捕获的异常,以便您可以在
catch
之外访问它。对于您所问的问题,您需要在原始线程中捕获该异常,将其移至主线程,然后在对
std::rethrow_exception
进行
join
编辑后调用
std::thread
(如果分配了
exception_ptr
) ,例如:

void testThread(const std::string &file, std::exception_ptr &exceptionPtr) {
  try {
    TestCSV csv(file);
    csv.writeToCSV(...);
  } catch (const std::exception &e) {
    exceptionPtr = std::current_exception();
  }
}

void testException(const std::string &file) {
  std::exception_ptr exceptionPtr = nullptr;
  std::thread input(testThread, file, std::ref(exceptionPtr));
  input.join();
  if (exceptionPtr)
    std::rethrow_exception(exceptionPtr);
}
© www.soinside.com 2019 - 2024. All rights reserved.