[英]Is it safe to use fork() with boost::asio::ip::tcp::iostream?
I'm attempting to daemonize a simple TCP client, and although the client works just fine in the foreground, daemonizing it causes strange behavior. 我正在尝试守护一个简单的TCP客户端,虽然客户端在前台工作得很好,但守护它会导致奇怪的行为。
As a test case, I have a server that, once you connect and send a single message ("connected"), will send you the number of seconds connected once per second. 作为一个测试用例,我有一台服务器,一旦你连接并发送一条消息(“已连接”),它将向你发送每秒连接一次的秒数。
If I daemonize (by calling Test::Connect(true)
), the connection drops after an arbitrary amount of time, even after successfully receiving a few numbers. 如果我守护进程(通过调用
Test::Connect(true)
),连接会在任意时间后丢失,即使在成功接收到一些数字之后也是如此。
If I don't daemonize (by calling Test::Connect(false)
), the connection stays active and I continue to receive numbers as expected. 如果我没有守护进程(通过调用
Test::Connect(false)
),连接保持活动状态,我会继续按预期接收数字。
#include <string>
#include <iostream>
#include <boost/asio.hpp>
#include <unistd.h>
class Test
{
public:
Test()
{
io = nullptr;
}
void Connect(bool daemonize)
{
io = new boost::asio::ip::tcp::iostream("localhost", "6500");
if ( io && *io )
{
*io << "connected" << std::endl;
if ( daemonize )
{
pid_t child = fork();
if ( child < 0 ) exit(EXIT_FAILURE);
else if ( child > 0 ) exit(EXIT_SUCCESS);
umask(0);
if ( setsid() < 0 ) exit(EXIT_FAILURE);
if ( chdir("/tmp") < 0 ) exit(EXIT_FAILURE);
child = fork();
if ( child < 0 ) exit(EXIT_FAILURE);
else if ( child > 0 ) exit(EXIT_SUCCESS);
}
std::string line;
while ( *io )
{
std::getline(*io, line);
std::cout << "Line (" << line.length() << "): " << line << std::endl;
}
}
delete io;
io = nullptr;
}
private:
boost::asio::ip::tcp::iostream *io;
}
I'm absolutely stumped as to what could be cutting off the input stream early (it appears that the loop exits because io->eof() == true
and thus (bool)*io == false
). 我很清楚可能会早期切断输入流(似乎循环退出,因为
io->eof() == true
,因此(bool)*io == false
)。 Since this only happens when trying to daemonize, should I avoid forking altogether? 因为这只是在尝试守护时发生的,我应该完全避免分叉吗? Is there a better way to send the process into the background programmatically (using C/C++ code only)?
有没有更好的方法以编程方式将进程发送到后台(仅使用C / C ++代码)?
I'm not sure if this is relevant, but do you need to call notify_fork
here, eg: 我不确定这是否相关,但是你需要在这里调用
notify_fork
,例如:
boost::asio::io_service io_service;
// ...
if ( daemonize )
{
io_service.notify_fork(boost::asio::io_service::fork_prepare);
pid_t child = fork();
if (child == 0) io_service.notify_fork(boost::asio::io_service::fork_child);
else io_service.notify_fork(boost::asio::io_service::fork_parent);
// ...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.