C /Linux:如何编写使用套接字的线程安全库

C++/Linux: how do you write a thread-safe library that uses sockets?

本文关键字:套接字 线程 安全 Linux 何编写      更新时间:2023-10-16

我想在linux下的C 编写一个库,该库将帮助应用程序使用某个协议(实际上是FastCGI)。库将收听套接字(TCP或UNIX),接收请求,将其转发到用户代码,并发送该用户代码生成的响应。

插座上会有许多连接,每个连接都会带有许多请求(可能同时存在 - 有一个交织机构)。用户代码(使用库)很可能是多线程的,以便同时处理多个请求。

我希望我的库变得强大,并对用户代码(包括使用的多线程类型)提出尽可能少的假设/要求。据我了解,Linux中的clone()函数可以以数十个不同的方式分配一个过程 - 有或没有共享存储器,共享文件句柄等。

这让我感到困惑,因为库代码突然发现自己的 fork()'ed,并且代码的多个副本可以突然从同一套接字读取并处理相同的请求。更糟糕的是 - 父过程可能会终止,只剩下子过程,这又产生了更多的子过程,甚至可能在不同的过程名称空间中 - 这是一团糟。

哪些Linux设施有助于协调需要访问相同外部资源(套接字)的相同代码的所有副本?实施此类线程安全库的标准方式是什么?我必须自己选择一个线程模型,并将其强加于图书馆的消费者?

不要直接使用 cloneclone to empartor 的线程库,例如 pthread)。不要使用很多fork -S(可能没有)。使用pthread -S。

您可以查看Libonion库的设计。它很小,实现HTTP服务器协议,因此与您的目标非常相似。

libonion为用户提供了各种为请求创建线程的模式。

您可以拥有类似于libonion -S的选项,无论是否创建每个FastCGI请求的新线程。

您可能想使用一些事件循环库,例如libevent或libev(围绕民意调查(2)-ing循环)。

并阅读好书,特别是高级Linux编程,以及在开始编码之前 pthread -s的一些教程。

此外,研究几个免费软件库的源代码与您的目标类似。

以似乎是在切线中脱离的风险,我建议您在每个处理器基础上以单线实现fastcgi。

原因:

  1. 更健壮。
  2. 避免与多线程相关的上下文开关开销,并保护您免受并发僵局等问题。
  3. 避免进叉()成本(尽管相当轻巧)并保护您免于处理潜在的儿童僵尸程序以及其他头痛。

这将使您选择使用以下方式实现FastCGI接口:

  1. 非阻滞同步I/O (反应堆设计模式):阻止读取或写入请求,将请求传递给该请求适当的处理程序,然后阻止下一个请求。
  2. 异步I/O (ProCractor设计模式):将读取请求传递给O/S支持I/O的操作系统完成事件。在窗户上,这将是IO完成端口在Linux上,例如Epoll()。