【发布时间】:2015-05-29 15:04:29
【问题描述】:
我正在尝试了解如何在多线程环境中正确使用 FastCGI。然而,当编译时,这个程序总是在 Apache 上产生一个Internal Server Error。我觉得我对 FastCGI 和 Apache 不够熟悉,无法诊断我的错误。
这个程序的一个简单的单线程等效程序运行得非常好。
我正在使用带有标志 -std=c++11 -lfcgi++ -lfcgi -lpthread 的 g++ 进行编译
下面是我正在使用的代码:
#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