error Too many open files
xiaoma565 opened this issue · 5 comments
My codes:
void HttpServer::HandleAccept(std::shared_ptr<ServerConnection> newConnection, const boost::system::error_code& ec)
{
// Check whether the Server was stopped by a signal before this
// completion handler had a chance to run.
if (!acceptor_.is_open()) {
return;
}
if (ec) {
LOG("[HttpServer] connection accept failed, error is %s\n", ec.what().c_str());
} else {
newConnection->Start();
count_++;
}
if (count_ > maxConnections_) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this] { return count_ <= maxConnections_; });
}
DoAccept();
}
void HttpServer::DoAccept()
{
auto &ioContext = ioContextPool_.GetIoContext();
std::shared_ptr<ServerConnection> newConnection = std::make_shared<ServerConnection>(ioContext, reqHandler_, this);
acceptor_.async_accept(newConnection->GetSocket(), boost::beast::bind_front_handler(&HttpServer::HandleAccept, this,
newConnection));
}
In my server connection
void ServerConnection::OnRead(boost::beast::error_code ec, std::size_t bytes_transferred)
{
boost::ignore_unused(bytes_transferred);
if(ec) {
LOG("[ServerConnection] OnRead error : %s\n", ec.what().c_str());
return DoClose();
}
keepAlive_ = req_.keep_alive();
version_ = req_.version();
auto fun = reqHandler_.GetFun(req_.method(), req_.target());
if (fun == nullptr) {
SendNormalRes(boost::beast::http::status::bad_request, "text/plain", "Invalid request\r\n");
} else {
fun(shared_from_this()); // 外部记得保存this的指针,防止引用计数到零后释放
}
if (keepAlive_) {
DoRead();
}
}
void ServerConnection::DoClose()
{
isClose = true;
try {
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_send);
} catch (const std::exception& e) {
LOG("[ServerConnection] DoClose error : %s\n", e.what());
}
server_->CloseOne();
}
Is that something wrong with "socket_.shutdown" ?
should I call "socket.close" after "socket.shutdown"?
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_send);
socket_.close();
It is hard to tell what could be wrong with the provided code sample. What happens inside server_->CloseOne()
? How many active connections do you have? Do they exceed the ulimit -n
?
It is hard to tell what could be wrong with the provided code sample. What happens inside
server_->CloseOne()
? How many active connections do you have? Do they exceed theulimit -n
?
server_->CloseOne()
code:
void HttpServer::CloseOne()
{
if (count_ > maxConnections_) {
count_--;
cv.notify_one();
} else {
count_--;
}
}
there are totally 1319 client connections, but i set single thread to accept.
the ulimit -n is 1024.
my io_contextpool is single thread too.
So the process should look something like this: accept -> do something -> close -> accept ...
but why the socket still opening?
I look at /proc/pid/fd with ll | grep socket | wc -l
and print 1010.
It seems that socket.close()
did not work?
there are totally 1319 client connections, but i set single thread to accept. the ulimit -n is 1024. my io_contextpool is single thread too. So the process should look something like this: accept -> do something -> close -> accept ... but why the socket still opening? I look at /proc/pid/fd with
ll | grep socket | wc -l
and print 1010. It seems thatsocket.close()
did not work?
socket.close()
should be sufficient. Is your application multi-threaded? What is the purpose of that condition variable, and how does it not block the call to io_context.run()
? It is likely you are encountering a concurrency or lifetime bug. I suggest starting with a minimal single-threaded example and then extending it.
there are totally 1319 client connections, but i set single thread to accept. the ulimit -n is 1024. my io_contextpool is single thread too. So the process should look something like this: accept -> do something -> close -> accept ... but why the socket still opening? I look at /proc/pid/fd with
ll | grep socket | wc -l
and print 1010. It seems thatsocket.close()
did not work?
socket.close()
should be sufficient. Is your application multi-threaded? What is the purpose of that condition variable, and how does it not block the call toio_context.run()
? It is likely you are encountering a concurrency or lifetime bug. I suggest starting with a minimal single-threaded example and then extending it.
the keypoint
headerCb = std::bind(&ClientConnection::ParserChunkHeader, self, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
bodyCb = std::bind(&ClientConnection::ParserChunkBody, self, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
p_->on_chunk_header(headerCb);
p_->on_chunk_body(bodyCb);
headerCb
and bodyCb
are ClientConnection's variables, they hold self
.
void ClientConnection::Close()
{
// Send a TCP shutdown
boost::beast::error_code ec;
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
// At this point the connection is closed gracefully
headerCb = nullptr;
bodyCb = nullptr;
}
in funcation Close()
we should set headerCb
and bodyCb
to nullptr otherwise the shared_ptr.use_count() will > 0.