【问题标题】:Is a server an infinite loop running as a background process?服务器是作为后台进程运行的无限循环吗?
【发布时间】:2011-02-13 08:17:57
【问题描述】:

服务器本质上是一个在端口上运行无限循环监听的后台进程吗?例如:

while(1){
   command = read(127.0.0.1:xxxx);
   if(command){
      execute(command);
   }
}

当我说服务器时,我显然不是指物理服务器(计算机)。我指的是 MySQL 服务器,或者 Apache 等。

完全披露 - 我没有时间浏览任何源代码。实际的代码示例会很棒!

【问题讨论】:

  • 离真相不远了。但是读取通常是对系统的阻塞读取,只有在有东西要返回时才会返回。没有收到数据 == 没有执行。
  • @eaanon01 - if(command) 基本上是我说“如果收到数据”的方式。
  • 我提到“实际的代码示例会很棒”,我更希望看到低级语言的代码示例。

标签: c theory


【解决方案1】:

存在三种“服务器”——分叉、线程和单线程(非阻塞)。它们通常都以您显示的方式循环,不同之处在于当有东西需要服务时会发生什么。

分叉服务就是这样。对于每个请求,都会调用 fork() 创建一个处理请求的新子进程,然后退出(或保持活动状态,以处理后续请求,具体取决于设计)。

线程服务类似于分叉服务,但不是一个全新的进程,而是创建一个新的线程 来服务请求。像分叉一样,有时线程会留下来处理后续请求。性能和占用空间的差异只是线程与分叉的差异。根据为客户端提供服务的内存使用情况(并且容易更改),通常最好不要克隆整个地址空间。这里唯一增加的复杂性是同步。

单个进程(也称为单线程)服务器只会派生一次以进行守护进程。它不会产生新线程,也不会产生子进程。它将继续 poll() 套接字以找出文件描述符何时准备好接收数据,或有数据可供处理。每个连接的数据都保存在自己的结构中,由各种状态(写入、等待 ACK、读取、关闭等)标识。如果做得好,这可能是一个非常有效的设计。您无需在等待工作时让多个子进程或线程阻塞,而是在请求准备就绪时使用单个进程和事件循环为请求提供服务。

在某些情况下,单线程服务会产生多个线程,但额外的线程无法处理传入的请求,可能(例如)在线程中设置本地套接字,允许管理员获取状态所有连接。

在谷歌上搜索一下非阻塞 http 服务器会产生一些有趣的手动 Web 服务器,编写为代码高尔夫挑战。

简而言之,不同之处在于进入无限循环后会发生什么,而不仅仅是无限循环:)

【讨论】:

    【解决方案2】:

    这或多或少是服务器软件通常所做的。

    通常它会变得更复杂,因为无限循环“仅”接受连接,并且每个连接通常可以处理多个“命令”(或在使用的协议中调用的任何内容),但基本思想大致是这样的。

    【讨论】:

    • 你是说我的伪代码+线程非常正确吗?
    • @Tony:是的。当然,伪代码意味着还有很多细节需要做对,但就是这样。
    • 不完全。剩下的就是如何
    【解决方案3】:

    说起来,是的。服务器只是“永远循环”并提供服务的东西。但是,通常您会发现“守护程序”会执行诸如在文件句柄或 /dev/null 上打开 STDOUT 和 STDERR 之类的事情,以及其他事情中的双叉。从某种意义上说,您的代码是一个非常简单的“服务器”。

    【讨论】:

      猜你喜欢
      • 2012-04-30
      • 1970-01-01
      • 2012-11-17
      • 2020-01-04
      • 1970-01-01
      • 2021-08-12
      • 1970-01-01
      • 2016-05-26
      • 2011-05-13
      相关资源
      最近更新 更多