【问题标题】:best way to write a linux daemon [closed]编写 linux 守护进程的最佳方法 [关闭]
【发布时间】:2010-11-15 16:29:45
【问题描述】:

为了工作,我需要编写一个 tcp 守护进程来响应我们的客户端软件,并且想知道是否有人对解决此问题的最佳方法有任何提示。

我应该像通常使用线程一样为每个新连接分叉吗?

【问题讨论】:

    标签: c++ linux daemon


    【解决方案1】:

    这取决于您的应用程序。线程和分叉都可以是完全有效的方法,也是单线程事件驱动模型的第三种选择。如果你能详细解释一下你在写什么,在提供建议时会有所帮助。

    就其价值而言,以下是一些一般准则:

    • 如果您没有共享状态,请使用分叉。
    • 如果您有共享状态,请使用线程或事件驱动系统。
    • 如果您需要在大量连接下获得高性能,请避免分叉,因为它具有更高的开销(尤其是内存使用)。而是使用线程、一个事件循环或多个事件循环线程(通常每个 CPU 一个)。

    通常分叉将是最容易实现的,因为一旦您分叉,您基本上可以忽略所有其他连接;由于额外的同步要求,线程次之;由于需要将您的处理转换为状态机,因此事件循环更加困难;并且多线程运行事件循环是其中最困难的(由于结合了其他因素)。

    【讨论】:

    • 分叉的内存开销并不算太糟糕,因为进程内存是在写入时复制的方式。主要的缺点是 fork() 所花费的时间,但是如果您不以高频率创建和破坏连接,那不应该是一个大问题。
    • 没错,但它可能不仅仅是一个带有文件描述符和输入缓冲区的小结构:)
    【解决方案2】:

    我建议任何一天都通过线程分叉连接。线程的问题在于共享内存空间,以及操作另一个线程的内存是多么容易。对于分叉的进程,进程之间的任何通信都必须由您有意完成。

    刚刚搜索并找到了这个 SO 答案:What is the purpose of fork?。你显然知道这个问题的答案,但该线程中的#1 答案对 fork() 的优势有很好的说明。

    【讨论】:

    • 另一个好处是中止线程可能会陷入困境或使整个应用程序崩溃。正如另一个答案中所建议的,您可以设置一个工作进程池。考虑有一个简单的委托人进程来排队工作人员合作处理的工作出队。此设置可让您更好地控制系统资源。
    【解决方案3】:

    除了@hobodave 的好答案之外,“每个连接分叉”的另一个好处是您可以通过使用inetd 或tcpserver 等非常简单地实现您的服务器:然后您可以使用标准输入和标准输出用于与套接字通信,并且不必做任何监听套接字管理(监听连接等)等。

    【讨论】:

      【解决方案4】:

      当然,另一种选择是预先分叉多个守护进程副本,让每个副本保持活动状态并继续响应请求。这完全取决于您的应用程序、预期负载和性能要求等。

      最简单最简单的方法是编写一个基于inetd的守护进程;您的软件可以忽略它通过 TCP 连接运行的事实,而只需通过标准输入/标准输出处理输入/输出。这在绝大多数情况下都很有效。

      【讨论】:

        【解决方案5】:

        如果您不打算每秒处理许多新连接,请考虑从 inetd 运行。否则……

        下载 OpenSSH 源代码。他们在权限分离方面做了大量工作,恰到好处,它是可移植的,而且它的安全性受到了比其他任何东西都多的审查。

        根据您的需要调整它,您可能可以扔掉大部分。当然要遵守许可协议。使用良好的 SCC 关注未来的补丁。

        在您有充分的证据证明这是一个真正的问题之前,不要担心分叉进程与线程的性能。 Apache 多年来一直使用简单的每客户端进程模型来运行最繁忙的站点。

        如果您真的有野心,您可以使用某种非阻塞异步 IO 模型。我喜欢 Boost.Asio,但我对 C++ 很感兴趣。

        确保您的代码正确处理信号。 HUP 重新加载配置。 TERM 正常关闭。

        不要尝试编写自己的日志文件。仅使用 syslog,或者只写入可以重定向到 syslog 的 stderr。尝试在所有日志略有不同的家用服务器上设置 logrotate 真的很痛苦。

        【讨论】:

          【解决方案6】:

          如果你想避免一起使用线程/分叉,我建议使用所有非阻塞 I/O 以及 libevent。 Libevent 是众所周知的事件驱动编程的高性能解决方案。

          【讨论】:

            【解决方案7】:

            查看ACE (C++/Java)。它有许多线程、事件和分叉 TCP 反应器,可满足您的通信需求。您还可以查看 Boost ASIO 做类似的事情

            【讨论】:

              猜你喜欢
              • 2011-02-13
              • 1970-01-01
              • 2023-03-26
              • 1970-01-01
              • 2012-10-03
              • 2011-06-05
              • 1970-01-01
              • 1970-01-01
              • 2011-03-26
              相关资源
              最近更新 更多