【问题标题】:Simple multithreaded fastcgi application always crashing简单的多线程 fastcgi 应用程序总是崩溃
【发布时间】:2015-05-29 15:04:29
【问题描述】:

我正在尝试了解如何在多线程环境中正确使用 FastCGI。然而,当编译时,这个程序总是在 Apache 上产生一个Internal Server Error。我觉得我对 FastCGI 和 Apache 不够熟悉,无法诊断我的错误。

这个程序的一个简单的单线程等效程序运行得非常好。

我正在使用带有标志 -std=c++11 -lfcgi++ -lfcgi -lpthreadg++ 进行编译

下面是我正在使用的代码:

#include "fcgio.h"
#include <vector>
#include <ostream>
#include <istream>
#include <thread>
#include <mutex>

std::mutex accept_mutex;

#define THREAD_COUNT (10)

void respond(){
  FCGX_Request request;
  FCGX_InitRequest(&request, 0, 0);
  fcgi_streambuf cout_fcgi_streambuf(request.out);

  std::ostream cout(&cout_fcgi_streambuf);

  for(;;) {
    accept_mutex.lock();
    if (FCGX_Accept_r(&request) < 0)
      break;
    accept_mutex.unlock();
    cout << "Content-type: text/html\r\n"
      << "\r\n"
      << "<html>\n"
      << "  <head>\n"
      << "    <title>Testing!</title>\n"
      << "  </head>\n"
      << "  <body>\n"
      << "    <h1>Hello, World!</h1>\n"
      << "</body>\n"
      << "</html>\n";

    FCGX_Finish_r(&request);
  }

}

int main(){
  FCGX_Init();
  std::vector<std::thread> threads(THREAD_COUNT);
  for(int i = 0 ; i < THREAD_COUNT ; i++)
    threads[i] = std::thread(respond);
  for(auto & x : threads)
    x.join();

}

这是我在 Apache 错误日志中发现的错误:

[Wed Mar 25 00:22:10.693368 2015] [fcgid:warn] [pid 11386:tid 139946920691456] (104)Connection reset by peer: [client 10.0.2.2:63490] mod_fcgid: error reading data from FastCGI server
[Wed Mar 25 00:22:10.693396 2015] [core:error] [pid 11386:tid 139946920691456] [client 10.0.2.2:63490] End of script output before headers: home2.fcgi
[Wed Mar 25 00:22:13.695752 2015] [fcgid:error] [pid 11384:tid 139947238573952] mod_fcgid: process /home/web/web/home2.fcgi(27007) exit(communication error), get unexpected signal 6

【问题讨论】:

  • 在退出main()之前加入你的线程怎么样?
  • 为了异常安全,永远不要自己打电话给lock()unlock()。而是使用std::lock_guard
  • 我还建议在 FCGX_Request 周围使用 RAII 包装器,以确保请求始终完成。
  • @user2899162 std::lock_guard 不是答案,否则我会这样发布。不,这是一种避免意外死锁的方法。
  • 这就是说你得到了SIGABRT,所以很可能你在respond() 中抛出了一个异常尝试在里面的代码周围做一个pokemon catch(例如catch(...)),看看会发生什么.

标签: c++ multithreading fastcgi


【解决方案1】:

我解决了问题中提出的问题。

我在 for(;;) 循环之前制作了 ofstream cout,它应该在循环内创建。

这是有道理的,因为每个单独的连接都有自己应该写入的流。

-

我的大型多线程应用程序的问题仍然存在——在我的大型程序中,我正确地实例化了我的ofstream。在创建我的最小示例时,我犯了一个错误,恰好在 Apache 中有相同的错误日志。但是,我的错误似乎与我发布的问题无关,现在我要开始寻找实际上造成错误的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    相关资源
    最近更新 更多