编写linux守护进程的最佳方法

时间:2009-07-31 03:59:34

标签: c++ linux daemon

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

我应该为每个新连接分叉,因为我会使用线程吗?

7 个答案:

答案 0 :(得分:9)

这取决于您的申请。线程和分叉都可以是完全有效的方法,也是单线程事件驱动模型的第三种选择。如果你能够更准确地解释你正在撰写的内容,那么在提供建议时会有所帮助。

对于它的价值,这里有一些一般准则:

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

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

答案 1 :(得分:3)

我建议任何时候都要在线程上进行连接。线程的问题是共享内存空间,以及操纵另一个线程的内存是多么容易。使用分叉进程,进程之间的任何通信都必须由您有意进行。

刚搜索过,发现这个答案:What is the purpose of fork?。你显然知道答案,但是那个帖子中的第一个答案对fork()的优点有好处。

答案 2 :(得分:1)

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

答案 3 :(得分:1)

当然,另一个选择是预先分配守护进程的几个副本,让每个守护进程保持活着并继续回答请求。这一切都取决于您的应用,预期负载和性能要求等。

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

答案 4 :(得分:1)

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

下载OpenSSH源代码。他们在权限分离方面投入了大量的工作,它是可移植的,并且对安全性进行了详细审查,而不仅仅是其他任何事情。

根据您的需求进行调整,您可能会抛出大部分内容。当然要遵守许可协议。使用良好的SCC跟踪未来的补丁。

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

如果你真的很有抱负,你可以使用某种非阻塞的异步IO模型。我喜欢Boost.Asio,但我很喜欢C ++。

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

不要尝试编写自己的日志文件。仅使用syslog,或者只写入可以重定向到syslog的stderr。试图在自制的服务器上设置logrotate是一件非常痛苦的事情,这些服务器的登录方式略有不同。

答案 5 :(得分:1)

如果您想避免一起使用线程/分叉,我建议您使用所有非阻塞I / O以及libevent。 Libevent作为事件驱动编程的高性能解决方案而闻名。

答案 6 :(得分:0)

查看ACE (C++/Java)。它有许多螺纹,事件和分叉TCP反应器,可满足您的通信要求。您还可以查看类似

Boost ASIO