I searched google and StackOverflow for anything similar to this but the closest ones were C code and the situation wasn\'t the same...
I have a program which starts ano
In short, based on the observed behaviors, the source of the problem is likely resulting from fork()
's behavior, as the child process will inherit a copy of the acceptor's open file descriptor. Closing the acceptor from within the child should resolve the problem.
When fork() occurs, the child process inherits copies of the parent's set of open file descriptors. Here is the relevant excerpt from the fork
documentation:
The child inherits copies of the parent's set of open file descriptors. Each file descriptor in the child refers to the same open file description as the corresponding file descriptor in the parent. This means that the two descriptors share open file status flags, current file offset, and signal-driven I/O attributes .
However, Boost.Asio has internal file descriptors that will also be duplicated. The io_service
needs to be prepared for fork()
, and notified after fork()
occurs. Boost.Asio document's the proper fork usage. Per the documentation, it is the program's responsibility to manage any file descriptors accessible via Boost.Asio's public API during a fork
:
// Inform the io_service that we are about to fork. The io_service cleans
// up any internal resources, such as threads, that may interfere with
// forking.
io_service_.notify_fork(boost::asio::io_service::fork_prepare);
if (0 == fork())
{
// Inform the io_service that the fork is finished and that this is the
// child process. The io_service uses this opportunity to create any
// internal file descriptors that must be private to the new process.
io_service_.notify_fork(boost::asio::io_service::fork_child);
// The child won't be accepting new connections, so we can close the
// acceptor. It remains open in the parent.
acceptor_.close();
system(...);
...
}
else
{
// Inform the io_service that the fork is finished (or failed) and that
// this is the parent process. The io_service uses this opportunity to
// recreate any internal resources that were cleaned up during
// preparation for the fork.
io_service_.notify_fork(boost::asio::io_service::fork_parent);
...
}
See Boost.Asio's process per connection for an example where the process forks from within a completion handler.