C++ 在没有取消的情况下,如何处理线程中的文件打开错误?

C++ 在没有取消的情况下,如何处理线程中的文件打开错误?,c++,multithreading,fopen,C++,Multithreading,Fopen,我有一个服务应用程序,它读取包含要打开的文件列表的配置文件。问题是当它在目录中找不到文件时,它会抛出一个异常,从而取消线程并停止服务应用程序 以下是在线程中调用的函数的代码块: FILE* file_; ServiceApp::File::File( const char* filename, const char* mode) : file_(fopen(filename, mode)) { if( !file_ ) { // throwing will stop th

我有一个服务应用程序,它读取包含要打开的文件列表的配置文件。问题是当它在目录中找不到文件时,它会抛出一个异常,从而取消线程并停止服务应用程序

以下是在线程中调用的函数的代码块:

FILE* file_;
ServiceApp::File::File( const char* filename, const char* mode) :
file_(fopen(filename, mode))
{
    if( !file_ )
    {
    // throwing will stop the service when file doesn't exist, what work around could we do?
    throw std::runtime_error("file open failure");
}
问题:
我们如何防止这种情况发生,以便在目录中找不到配置文件中列出的文件时,应用程序将忽略该文件并继续该过程?

最简单的方法是尝试在线程中捕获您自己的异常,然后检查它是否为该异常(忽略它),如果是其他例外的话,就重播

我不确定是否可以将信息添加到引发异常的位置,或者是遗留代码?在后一种情况下,您将不得不求助于字符串比较,这当然是丑陋的。无论如何

// pseudo-code
while(GotFilesInQueue())
{
  try
  {
    LoadNextFile();
  }
  catch(std::exception& e)
  {
    if(!IgnoreExceptionPredicate(e))
    {
      throw;
    }
  }
}

我建议使用
std::async
。如果通过
std::async
运行的函数抛出异常,异常将保存在
std::future
中。当您调用
std::future::get()
时,我将被重新调用。然而,如果您不这样做,它将被“忽略”,因此您的应用程序将继续运行

例如:

auto lambda = [] {
    throw std::runtime_error("error");
};

auto handle = std::async(std::launch::async, lambda);

有关
std::async
read.

的详细信息,最简单的方法是在处理文件的代码块周围放置try/catch语句。
在其他特殊情况下(例如,当读取在读取过程中消失的网络文件时),您很可能会遇到抛出的其他异常,因此请仔细检查代码中的其他异常

这是否仅适用于c++0x?@Owen yes。如果您不能使用
c++11
,boost可能也能工作。