对于工作,我需要编写一个tcp守护进程来响应我们的客户端软件,并想知道是否有任何人有关于最佳方法的任何提示。
我应该为每个新连接分叉,因为我会使用线程吗?
答案 0 :(得分:9)
这取决于您的申请。线程和分叉都可以是完全有效的方法,也是单线程事件驱动模型的第三种选择。如果你能够更准确地解释你正在撰写的内容,那么在提供建议时会有所帮助。
对于它的价值,这里有一些一般准则:
通常分叉是最容易实现的,因为一旦你分叉就可以基本上忽略所有其他连接;由于额外的同步要求,下一个线程最难;由于需要将处理转换为状态机,事件循环更加困难;并且运行事件的多个线程循环最困难(由于结合其他因素)。
答案 1 :(得分:3)
我建议任何时候都要在线程上进行连接。线程的问题是共享内存空间,以及操纵另一个线程的内存是多么容易。使用分叉进程,进程之间的任何通信都必须由您有意进行。
刚搜索过,发现这个答案:What is the purpose of fork?。你显然知道答案,但是那个帖子中的第一个答案对fork()的优点有好处。
答案 2 :(得分:1)
除了@ hobodave的好答案之外,“每个连接分叉”的另一个好处是,您可以使用inetd
或tcpserver
之类的方式非常简单地实现您的服务器:您可以使用标准用于与套接字通信的输入和标准输出,不必进行任何监听套接字管理(监听连接等)等。
答案 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