C++ 使用fork()和#x2B;Linux中带boost::asio的execlp

C++ 使用fork()和#x2B;Linux中带boost::asio的execlp,c++,sockets,network-programming,fork,boost-asio,C++,Sockets,Network Programming,Fork,Boost Asio,我有一个程序,它在TCP端口上侦听特定字符串,并使用execlp调用启动应用程序。我正在执行fork()以在调用execlp之前启动一个子进程。在此启动之后,父进程再次开始在同一端口上侦听。我正在关闭子进程中的套接字 我已经在boost::asio::tcp_socket上编写了一个包装器,在绑定socket之前,我将addr_reuse选项设置为true 现在我的问题是在Linux中,在应用程序启动几次之后,我遇到了地址重用错误。在我的程序中,它不断尝试接受连接(或者更准确地说,尝试安排接受到

我有一个程序,它在TCP端口上侦听特定字符串,并使用
execlp
调用启动应用程序。我正在执行
fork()
以在调用
execlp
之前启动一个子进程。在此启动之后,父进程再次开始在同一端口上侦听。我正在关闭子进程中的套接字

我已经在
boost::asio::tcp_socket
上编写了一个包装器,在绑定socket之前,我将
addr_reuse
选项设置为
true

现在我的问题是在Linux中,在应用程序启动几次之后,我遇到了地址重用错误。在我的程序中,它不断尝试接受连接(或者更准确地说,尝试安排接受到
boost::asio::io_服务
),直到绑定成功,然后接受成功。所以我在这个循环中收到了错误

奇怪的是,如果我关闭(或杀死)启动的可执行文件,这个错误就不会出现,这意味着
bind
成功。我确信在已启动的应用程序中,同一端口不会在任何地方使用。 我正在使用异步套接字操作。知道我为什么会犯这个错误吗

下面是我在套接字上接受的方式:(在开始新接受之前,我还调用
boost::asio::tcp\u套接字(\u tcpSocket)
shared指针上的reset。)

以下是我的分叉方式:

pid_t pid = fork();
switch (pid)
{
    case 0:
    {
        /// close all sockets for child process. as it might cause addr reuse error in parent process
        _asyncNO->closeAll();
        std::string binary = "<binaryName>";
        std::string path = "<binaryPath>";
        if ( execlp( path.c_str(), binary.c_str(), controllerIP.c_str(), (char *)0 ) == -1 )
        {
            LOG_ERROR("System call failed !!")
        }
    }
    break;

    default:
}
pid_t pid=fork();
开关(pid)
{
案例0:
{
///关闭子进程的所有套接字。因为这可能导致父进程中的addr重用错误
_asyncNO->closeAll();
std::string binary=“”;
std::string path=“”;
if(execlp(path.c_str()、binary.c_str()、controllerIP.c_str(),(char*)0)=-1)
{
日志错误(“系统调用失败!!”)
}
}
打破
违约:
}

为了简单起见,我删除了日志记录。

正如@TannerSansbury在评论中所说,这可能是因为Boost.Asio需要通知
fork()

相关章节转载如下:

Asio支持使用
fork()
系统调用的程序。如果程序在适当的时间调用io服务.notify\u fork(),Boost.Asio将重新创建任何内部文件描述符(例如用于唤醒反应堆的“自管道技巧”描述符)。通知通常按以下方式执行:

io\u服务\u.notify\u fork(boost::asio::io\u服务::fork\u prepare);
如果(fork()==0)
{
io\ U服务\通知\分支(boost::asio::io\ U服务::分支\子级);
// ...
}
其他的
{
io\ U服务\通知\分叉(boost::asio::io\ U服务::分叉\父级);
// ...
}
通过重写
io\u service::service::service::fork\u service()
virtual函数,还可以使用户定义的服务具有fork意识

请注意,通过Boost.Asio的公共API访问的任何文件描述符(例如
basic_socket
posix::stream_descriptor
)在fork期间都不会更改。项目有责任根据需要对其进行管理


Boost.Asio需要被通知
fork()
;否则,可能会发生未定义的行为。可能值得实现中提到的
fork()
通知,并看看这是否解决了问题。
pid_t pid = fork();
switch (pid)
{
    case 0:
    {
        /// close all sockets for child process. as it might cause addr reuse error in parent process
        _asyncNO->closeAll();
        std::string binary = "<binaryName>";
        std::string path = "<binaryPath>";
        if ( execlp( path.c_str(), binary.c_str(), controllerIP.c_str(), (char *)0 ) == -1 )
        {
            LOG_ERROR("System call failed !!")
        }
    }
    break;

    default:
}