使用带有boost :: asio :: ip :: tcp :: iostream的fork()是否安全?

时间:2013-01-10 14:59:37

标签: c++ c++11 posix fork boost-asio

我正在尝试守护一个简单的TCP客户端,尽管客户端在前台工作得很好,但守护它会导致奇怪的行为。

作为一个测试案例,我有一台服务器,一旦你连接并发送一条消息(“已连接”),它将向你发送每秒连接一次的秒数。

如果我守护进程(通过调用Test::Connect(true)),连接会在任意时间后丢失,即使在成功接收到一些数字后也是如此。

如果我没有守护进程(通过调用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;
}

我对于早期切断输入流的问题感到非常难过(似乎循环退出是因为io->eof() == true因此(bool)*io == false)。因为这只是在尝试守护时发生的,我应该完全避免分叉吗?有没有更好的方法以编程方式将进程发送到后台(仅使用C / C ++代码)?

1 个答案:

答案 0 :(得分:0)

我不确定这是否相关,但您是否需要在此处致电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);
  // ...
}