Linux C++ 服务端运行时刻接受输入。

ChenQi 发布于 2011/08/28 00:23
阅读 1K+
收藏 1

用c/s模型写了个socket通信的程序。现在想要让服务端能在运行时刻(一直在接受客户端的请求并且处理)检查标准输入或者某个文件,从而来对服务端进行控制(比如停止或者启用某项服务,或者多某项服务的参数进行改变)。那么通过什么方法可以达到这一目的呢?

我现在的想法是,让服务端支持多线程,其中一个线程每隔0.5秒检查某一个文件或者标准输入。

我现在的服务端是用多进程来支持多个客户端的。不知道这样写会不会有问题?

有没有其他的一些办法呢?

Good Luck :)

加载中
0
ckh
ckh
父进程多线程,或者I/O复用
ckh
ckh
@ChenQi : WaiTing 的例子就是一个I/O复用+多线程的模型了
ChenQi
ChenQi
I/O复用是怎么回事啊?
asdfsx
asdfsx
+1
0
jlmpp
jlmpp

你的意思是不是:先运行Socket监听服务程序,同时创建一个0.5s轮询标准输入的线程,然后当每一个客户端连接时为它创建一个进程保持双向连接,当客户端通过Socket发送服务请求时,通过向Socket监听服务程序发送进程消息,然后由轮询线程来执行请求?对这种做法我不太支持,1)为每一个客户创建一个进程开销大,一般不建议这么做。2) 轮询你所说的标准输入,让人摸不着头脑,为什么不等到有客户请求时再去检查处理?3)多进程间通讯效率低且麻烦。

建议做法:  运行Socket监听服务程序,在指定端口监听客户连接,同时打开标准输入返回句柄(windows平台)或描述符(Linux平以),对每个客户连接,创建一个对应的线程,并将句柄或描述符通过线程参数传递给它,当客户发送服务请求指令(自已定义协议),对应的线程直接访问标准输入的句柄或描述符来处理即可。(注意多线程访问同一资源时的同步处理)

 

 

ChenQi
ChenQi
Thank you:) 就是说服务端完全抛弃多进程,改用多线程编程? 每当客户端有请求时去查询标准输入? 确实比我的方法好:)
0
yaoboyuan
yaoboyuan

没见过服务器端不用多线程的,IO复用的设计思想还不是很适应,还是多线程让人感觉逻辑模块独立

ChenQi
ChenQi
Thank you:)
0
悟庭
悟庭

真巧。。我正在写类似的东西。。用纯socket api模拟出windows iocp模型。。实现高性能处理。

利用select()函数和多线程,配合几个队列。。就能写出。

jlmpp说的这种方法可行,但无法高效执行。原因是,如果客户连接很大,比如2000,这就意味着有2000个可执行线程,线程是高消耗系统资源的东西,如果太多,则系统会花费大量的CPU周期去分派切换,这样反而降低了处理效率。。

事实上,一个程序同时的可执行线程最好不要超过{CPU核数*2 + 2}个。

f
fly2010love
用来测试或者学习还行,真正用到实处的服务器就算你加入select加上多线程还是不够用的,select内核定义最多1024个链接;epoll或者boost会更实际
ChenQi
ChenQi
soga:)多线程+重复服务么?真想看一看啊~~!
0
Lunar_Lin
Lunar_Lin

对于服务器,不怎么用多进程,当然处理客户端请求的线程个数同楼上所说.

来一个请求后,丢给线程池.线程处理完成后,继续等待请求. 而不是专门的一对一的形式.(不然线程数太多了,且很容易想像到 它们绝大多数都是短命鬼,或长期休息型.)

ChenQi
ChenQi
Thank you for your help:)
0
悟庭
悟庭

基本上的思路就是

1. 开一个线程,用来接受客户连接,并把它放进一个“池”中。这个线程就循环干这一件事。

2. 开第二个线程,用来检测“池”中所有连接的[可读,可写,错误]状态,并把检测到的结果作为待处理消息,抛入一个队列中。。

3. 开N个工作线程,用来处理待处理队列中的客户连接,由于已经知道状态,可以无阻塞的调用recv,send,等函数..

基本思路就是这样,N个工作线程数量可指定,这样,可以根据不同服务器的硬件配置调整。

ChenQi
ChenQi
geili
LoveJJ2011
LoveJJ2011
这个思路不错,现在好多服务器都是这样的设计思想
0
yaoboyuan
yaoboyuan

引用来自“WaiTing”的答案

真巧。。我正在写类似的东西。。用纯socket api模拟出windows iocp模型。。实现高性能处理。

利用select()函数和多线程,配合几个队列。。就能写出。

jlmpp说的这种方法可行,但无法高效执行。原因是,如果客户连接很大,比如2000,这就意味着有2000个可执行线程,线程是高消耗系统资源的东西,如果太多,则系统会花费大量的CPU周期去分派切换,这样反而降低了处理效率。。

事实上,一个程序同时的可执行线程最好不要超过{CPU核数*2 + 2}个。

这个说法很赞同

0
Lunar_Lin
Lunar_Lin
参看linux 下的epoll,windows下的iocp, 或者直接使用 boost::asio网络库(底层分别根据系统使用epoll, iocp).
0
i
ibmo
利用本地的输入文件控制服务器,这是典型的进程间通信,在linux中,可以考虑使用本地的socket连接或者命名管道,这样就可以用 select() 函数同时监控本地的socket连接和远程的socker连接。
ChenQi
ChenQi
谢谢,我先研究下:)
0
薛德章
薛德章

引用来自“夜游神(Lunar)”的答案

参看linux 下的epoll,windows下的iocp, 或者直接使用 boost::asio网络库(底层分别根据系统使用epoll, iocp).
赞成
返回顶部
顶部