linux - 服务器运行在 linux 内核中。 listen 是否应该在线程中发生?

标签 linux networking kernel

我正在 linux 内核中编写一个客户端/服务器(是的。在内核中。它的设计决策已被采纳并最终确定。它不会改变)

服务器从原始套接字读取传入的数据包。这些数据包的传输协议(protocol)(原始套接字正在其上监听)是自定义的,类似于 UDP。简而言之,我不必监听传入的连接,然后 fork 一个线程来处理该连接。

我必须处理来自原始套接字的任何 IP 数据报。我将在原始套接字上无限循环地继续读取数据包。在用户级等效程序中,我会创建一个单独的线程并继续监听传入的数据包。

现在对于内核级服务器,我怀疑是否应该在单独的线程中运行它,因为:

  1. 我认为 read() 是一个 I/O 操作。所以在 read() 内部的某处,内核必须调用 schedule() 函数来放弃处理器的控制。因此,在原始套接字上调用 read() 之后,当前内核事件上下文将被搁置(可能放休眠眠队列?),直到数据包可用。当数据包到达时,内核中断上下文将发出信号,表明正在队列中休眠的读取上下文再次准备好运行。我在这里故意使用“上下文”而不是“线程”。因此我不需要单独的内核线程。

  2. 另一方面,如果 read() 不放弃控制权,那么整个内核将被阻塞。

任何人都可以提供有关我应该如何设计我的服务器的提示吗? 第 1 点中提出的论点的谬误是什么?

最佳答案

我不确定内核中是否需要原始套接字。在内核中,您可以添加一个 netfilter 钩子(Hook),或者注册其他东西(???)来接收所有数据包;这可能就是您想要的。

如果您确实在内核中使用了原始套接字,那么您可能需要有一个内核线程(即由 kernel_thread 启动)来调用它的 read()。但它不必是内核线程,它可以是用户空间线程,它只是进行特殊的系统调用或设备调用以调用所需的内核模式例程。

如果你注册了一个钩子(Hook),它调用的上下文可能是不应该做太多处理的东西;我不知道那可能是什么,它可能是“下半部分处理程序”或“tasklet”,无论是什么(这些类型的控制结构不断从一个版本更改为另一个版本)。我希望它实际上不是中断服务例程。


回答你原来的问题:

  1. 是的,sys_read 会阻塞调用线程,无论它是内核线程还是用户空间线程。系统不会挂起。但是,如果调用线程不处于阻塞有意义的状态,内核将 panic(调度中断或其他)

是的,您需要在单独的线程中执行此操作,不,它不会挂起系统。然而,在内核模式下进行系统调用是非常不确定的,尽管它确实有效(某种程度上)。

但是如果你安装了某种钩子(Hook),你就不需要做任何事情了。

关于linux - 服务器运行在 linux 内核中。 listen 是否应该在线程中发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/615483/

相关文章:

go - gRPC 到远程服务器的带宽较慢

networking - 使用 bufio.NewReader(conn) 阅读整条消息

c++ - 监视内核注册表更改

linux - 为什么 Linux 内核内存子系统被命名为 slab

Windows 中的 Linux 内核检查

c - 我的 execvp 使用有什么问题?

python - 如何在带有gpu的tensorflow安装中处理 `GCC`?

android - 设备上没有剩余空间但 SD 卡未满

networking - TCP/IP 建立连接/什么建立连接

linux - 远程 X session 很慢 [centos5]