当其他线程处于活动状态并且具有 try-catch 时,无法在主线程中捕获异常

can't catch exception in main thread when other thread active and has try-catch

主线程无法捕获异常(在主线程中抛出),而另一个具有 try-catch 的线程仍处于活动状态。如何解决? 示例:

int main()
{
  // try-catch of main thread
  try
  {
     // run a thread
     std::thread cThread([]()
     {
        // try-catch of secondary thread
        try
        {
           // makes thread works for 500 ms in order main thread will call
           // throw while thread is still active.  
           std::this_thread::sleep_for(std::chrono::milliseconds(500));
        }
        catch (...)
        {
        }
     });

     // Any call to throw BEFORE thread is finished, won't be catch.  
     // HOW TO SOLVE IT??
     throw 1;

     // wait thread finished
     cThread.join();

     // IF YOU PUT THE "throw 1" HERE (AFTER THREAD FINISHED), IT WILL BE 
     // CATCH.
   }
   catch (int e)
   {
      std::cout << "Catched exception " << e << " in main";
   }

   return 0;
}

与其说没有捕获到异常,还不如说销毁可连接线程会终止进程。 所以你的程序在异常处理程序可以执行之前终止。

如果在 try-catch 块之外声明线程,异常将被捕获。
请记住,如果抛出异常,您还需要加入线程。

你搞错了。我是说,你误会了什么。

这不可能是试探。 'throw' 和 'try-catch' 是线程内的东西,它们只存在于当前线程,无论它在抛出时是什么,主线程或其他线程。

另一个线程无法捕获当前线程抛出的异常。异常不会跨线程,除非你真的想要它并实现它,例如,当前线程上的某些东西捕获异常并将它们传递给其他线程然后 re-throws/etc 这些异常在那里。你没有这样的东西,所以不可能。

您在抛出后有一个 join() 调用,您希望 throw 1 会跳过它。这是真的。但是,范围内还有 std::thread cThread 变量。

因为线程是 运行ning,并且由于 throw 1 线程还没有被 join()ed,那么 expected看到会是程序终止(参见), because the destructor of std::thread would detect the un-join()ed thread. That means, the std::cout << "Catched exception " << e << " in main"; should never be called. Even if the thread has somehow finished, your program should still terminate, since it does not change the fact it was not join()ed (see https://en.cppreference.com/w/cpp/thread/thread/joinable

但是,根据库、编译器、调试器等,您看到的效果可能会有所不同。例如,如果你在调试器中 运行 它,它可能会等到所有线程完成,你会得到 "waiting until inner thread finished" 的效果。不好说。

如果您确实看到 "Catched exception " << e << " 行 运行ning,那您就遇到了真正的问题。要么您 运行 正在使用当前代码以外的东西,要么您的 stdlib 已损坏。例如,损坏的 stdlib 可能会在 std::thread 的析构函数中执行静默 join() 而不是终止程序。谁知道。损坏的库可以做很多事情。

感谢molbdnilo and quetzalcoatl。 我现在通过使用 std::async 而不是 std::thread 来使代码工作:

首先,问题与线程中的try-catch无关。这是我的错误想法。所以这是一个失败代码:

int main()
{
  // try-catch of main thread
  try
  {
     // run a thread
     std::thread cThread([]()
     {
     });

     // Any call to throw BEFORE thread join won't be catch.  
     // HOW TO SOLVE IT??
     throw 1;

     // wait thread finished
     cThread.join();

     // IF YOU PUT THE "throw 1" HERE (AFTER THREAD FINISHED), IT WILL BE 
     // CATCH.
   }
   catch (int e)
   {
      std::cout << "Catched exception " << e << " in main";
   }

   return 0;
}

以及有效的代码:

int main()
{
  std::future<void> cF;

  // try-catch of main thread
  try
  {
     // run a thread
     cF = std::async(std::launch::async, []()
     {
     });

     // You can call throw , it will be catch :)  
     throw 1;

     // wait thread finished
     if (cF.valid())
     {
        cF.get();
     }
   }
   catch (int e)
   {
      std::cout << "Catched exception " << e << " in main";
   }

   return 0;
}