2

我想在 Linux 下用 C++ 编写一个库,以帮助应用程序使用某种协议(实际上是 FastCGI)。该库将侦听套接字(TCP 或 Unix),接收请求,将它们转发给用户代码,并发送由所述用户代码生成的响应。

套接字上将有许多连接,每个连接将携带许多请求(可能同时 - 存在交错机制)。用户代码(使用库)很可能是多线程的,以便并行处理多个请求。

我希望我的库是健壮的,并且对用户代码做出尽可能少的假设/要求,包括使用的多线程类型。据我了解,clone()Linux 中的函数可以以几十种不同的方式分叉一个进程——有或没有共享内存、共享文件句柄等。如何实现多线程的决定应该留给用户。

这让我很困惑,因为库代码会突然发现自己fork()被编辑了,并且代码的多个副本可能会突然从同一个套接字读取并处理同一个请求。更糟糕的是——父进程可能会终止,只留下子进程,这反过来又会产生更多的子进程,甚至可能在不同的进程命名空间中——这是一团糟。

有哪些 Linux 工具可以帮助协调需要访问相同外部资源(套接字)的相同代码的所有副本?实现这种线程安全库的标准方法是什么?我必须自己选择一个线程模型并将其强加给我的图书馆的消费者吗?

4

2 回答 2

0

不要直接使用clone(保留clone给线程库的实现pthread者,如)。不要使用很多fork-s (可能没有)。去使用pthread-s。

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

libonion为用户提供各种模式来为请求创建或不创建线程。

您可以使用类似于libonion-s 的选项来为每个 FastCGI 请求创建或不创建新线程。

您可能想要使用一些事件循环库,如libeventlibev(围绕poll(2) -ing 循环)。

在开始编码之前阅读好书,特别是Advanced Linux Programming和一些关于Pthread -s的教程。

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

于 2012-11-11T14:41:24.357 回答
-1

冒着看似偏离正题的风险,我建议在每个处理器的单个线程上实现 fastcgi 。

原因:

  1. 更健壮。
  2. 避免与多线程相关的上下文切换开销,并保护您免受并发死锁等问题的影响。
  3. 避免进程 fork() 成本(尽管加起来很轻)并保护您免于处理潜在的子僵尸进程以及其他令人头疼的问题。

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

  1. 非阻塞同步 I/OReactor设计模式):阻塞直到有读或写请求进来,将请求传递给适当的处理程序,然后阻塞直到下一个请求进来。
  2. 异步 I/OProactor设计模式):将读写请求传递给 O/S 支持 I/O 完成事件的操作系统。在 Windows 上是IO 完成端口 ,在 Linux 上是epoll()之类的。
于 2012-11-11T15:01:50.253 回答