Linux C++ 服务端运行时刻接受输入。
用c/s模型写了个socket通信的程序。现在想要让服务端能在运行时刻(一直在接受客户端的请求并且处理)检查标准输入或者某个文件,从而来对服务端进行控制(比如停止或者启用某项服务,或者多某项服务的参数进行改变)。那么通过什么方法可以达到这一目的呢?
我现在的想法是,让服务端支持多线程,其中一个线程每隔0.5秒检查某一个文件或者标准输入。
我现在的服务端是用多进程来支持多个客户端的。不知道这样写会不会有问题?
有没有其他的一些办法呢?
Good Luck :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(20)
基本上的思路就是
1. 开一个线程,用来接受客户连接,并把它放进一个“池”中。这个线程就循环干这一件事。
2. 开第二个线程,用来检测“池”中所有连接的[可读,可写,错误]状态,并把检测到的结果作为待处理消息,抛入一个队列中。。
3. 开N个工作线程,用来处理待处理队列中的客户连接,由于已经知道状态,可以无阻塞的调用recv,send,等函数..
基本思路就是这样,N个工作线程数量可指定,这样,可以根据不同服务器的硬件配置调整。
这个思路不错,现在好多服务器都是这样的设计思想
引用来自“WaiTing”的答案
真巧。。我正在写类似的东西。。用纯socket api模拟出windows iocp模型。。实现高性能处理。
利用select()函数和多线程,配合几个队列。。就能写出。
jlmpp说的这种方法可行,但无法高效执行。原因是,如果客户连接很大,比如2000,这就意味着有2000个可执行线程,线程是高消耗系统资源的东西,如果太多,则系统会花费大量的CPU周期去分派切换,这样反而降低了处理效率。。
事实上,一个程序同时的可执行线程最好不要超过{CPU核数*2 + 2}个。
参看linux 下的epoll,windows下的iocp, 或者直接使用 boost::asio网络库(底层分别根据系统使用epoll, iocp).
利用本地的输入文件控制服务器,这是典型的进程间通信,在linux中,可以考虑使用本地的socket连接或者命名管道,这样就可以用 select() 函数同时监控本地的socket连接和远程的socker连接。
谢谢,我先研究下:)
引用来自“夜游神(Lunar)”的答案
参看linux 下的epoll,windows下的iocp, 或者直接使用 boost::asio网络库(底层分别根据系统使用epoll, iocp).
对于服务器,不怎么用多进程,当然处理客户端请求的线程个数同楼上所说.
来一个请求后,丢给线程池.线程处理完成后,继续等待请求. 而不是专门的一对一的形式.(不然线程数太多了,且很容易想像到 它们绝大多数都是短命鬼,或长期休息型.)
Thank you for your help:)
用来测试或者学习还行,真正用到实处的服务器就算你加入select加上多线程还是不够用的,select内核定义最多1024个链接;epoll或者boost会更实际
soga:)多线程+重复服务么?真想看一看啊~~!
真巧。。我正在写类似的东西。。用纯socket api模拟出windows iocp模型。。实现高性能处理。
利用select()函数和多线程,配合几个队列。。就能写出。
jlmpp说的这种方法可行,但无法高效执行。原因是,如果客户连接很大,比如2000,这就意味着有2000个可执行线程,线程是高消耗系统资源的东西,如果太多,则系统会花费大量的CPU周期去分派切换,这样反而降低了处理效率。。
事实上,一个程序同时的可执行线程最好不要超过{CPU核数*2 + 2}个。
Thank you:)
没见过服务器端不用多线程的,IO复用的设计思想还不是很适应,还是多线程让人感觉逻辑模块独立
Thank you:) 就是说服务端完全抛弃多进程,改用多线程编程? 每当客户端有请求时去查询标准输入? 确实比我的方法好:)
你的意思是不是:先运行Socket监听服务程序,同时创建一个0.5s轮询标准输入的线程,然后当每一个客户端连接时为它创建一个进程保持双向连接,当客户端通过Socket发送服务请求时,通过向Socket监听服务程序发送进程消息,然后由轮询线程来执行请求?对这种做法我不太支持,1)为每一个客户创建一个进程开销大,一般不建议这么做。2) 轮询你所说的标准输入,让人摸不着头脑,为什么不等到有客户请求时再去检查处理?3)多进程间通讯效率低且麻烦。
建议做法: 运行Socket监听服务程序,在指定端口监听客户连接,同时打开标准输入返回句柄(windows平台)或描述符(Linux平以),对每个客户连接,创建一个对应的线程,并将句柄或描述符通过线程参数传递给它,当客户发送服务请求指令(自已定义协议),对应的线程直接访问标准输入的句柄或描述符来处理即可。(注意多线程访问同一资源时的同步处理)
+1
I/O复用是怎么回事啊?
WaiTing 的例子就是一个I/O复用+多线程的模型了
父进程多线程,或者I/O复用