如何为服务器编写Main-Loop?

时间:2011-09-10 13:02:05

标签: c++ cycle

我有一个用c ++编写的简单fcgi服务器 - 现在它是单线程的。我看到主循环,例如

accept_connections();
handle_data();`
handle_connections();

但如果我想同时回复每个客户呢?因为如果我理解这一点,服务器首先接受新连接并迭代它们并进行处理。但这可能不是很好,因为例如上传(当一个客户上传,其他人必须等待。)或DoS像Slowloris。服务器如何一次完成多个客户端?我看到一台服务器是单线程的 - 并且做到了。

怎么做?

3 个答案:

答案 0 :(得分:2)

使用单个线程查看Boost.Asio异步I / O.

答案 1 :(得分:2)

我之前解决了,但我想回答我的问题。

我做的解决方案:

  • 1个接受者线程 - (接受()用于新的传入连接 阻止行为)并使用负载平衡分配与网络线程的连接
  • N个网络线程,其中N =(每1000个客户端1个线程),具有非阻塞行为:
    • 初始化
    • 服务器正在运行时
      • 设置超时观察器(用于禁用事件循环中的阻止)
      • 运行事件循环
      • 停止超时观察者
      • 从接受者线程添加新套接字
      • 迭代连接运行Update(),尝试刷新输出,检查关闭等等,如果Update()返回-1,从列表中删除连接
    • 结束时
    • 释放并关闭所有连接并释放所有已分配的内存
    • 返回
  • 工作线程与posix信号量等待作业(线程池作为管理)
  • (可选)后台线程,具有低优先级,用于安排和检查,删除例如令牌,会话等。很多人都在睡觉。

我写了自定义fastcgi处理程序。我还使用libev进行网络线程,缓冲和直接输出以及自动唤醒和禁用写入事件。使用valgrind进行调试。编译器铿锵。

对其他答案的反应:

我不想使用每个连接的线程,因为它在产生时有一些成本,而且如果有很多线程,也会有减速和更高的内存使用量。

我没有使用boost asio,因为我不喜欢框架,异步IO不是我想要的。

答案 2 :(得分:0)

您可以为每个传入连接生成一个新线程。要提高效率,请使用线程池以避免始终创建新线程的开销。

有替代/更好的方法,但这个很简单,你可以继续使用阻塞套接字。请注意从线程访问共享资源时的同步问题!