C /Linux:如何编写使用套接字的线程安全库
C++/Linux: how do you write a thread-safe library that uses sockets?
我想在linux下的C 编写一个库,该库将帮助应用程序使用某个协议(实际上是FastCGI)。库将收听套接字(TCP或UNIX),接收请求,将其转发到用户代码,并发送该用户代码生成的响应。
插座上会有许多连接,每个连接都会带有许多请求(可能同时存在 - 有一个交织机构)。用户代码(使用库)很可能是多线程的,以便同时处理多个请求。
我希望我的库变得强大,并对用户代码(包括使用的多线程类型)提出尽可能少的假设/要求。据我了解,Linux中的clone()
函数可以以数十个不同的方式分配一个过程 - 有或没有共享存储器,共享文件句柄等。
这让我感到困惑,因为库代码突然发现自己的 fork()
'ed,并且代码的多个副本可以突然从同一套接字读取并处理相同的请求。更糟糕的是 - 父过程可能会终止,只剩下子过程,这又产生了更多的子过程,甚至可能在不同的过程名称空间中 - 这是一团糟。
哪些Linux设施有助于协调需要访问相同外部资源(套接字)的相同代码的所有副本?实施此类线程安全库的标准方式是什么?我必须自己选择一个线程模型,并将其强加于图书馆的消费者?
不要直接使用 clone
( clone
to empartor 的线程库,例如 pthread
)。不要使用很多fork
-S(可能没有)。使用pthread
-S。
您可以查看Libonion库的设计。它很小,实现HTTP服务器协议,因此与您的目标非常相似。
libonion
为用户提供了各种为请求创建线程的模式。
您可以拥有类似于libonion
-S的选项,无论是否创建每个FastCGI请求的新线程。
您可能想使用一些事件循环库,例如libevent或libev(围绕民意调查(2)-ing循环)。
并阅读好书,特别是高级Linux编程,以及在开始编码之前 pthread -s的一些教程。
此外,研究几个免费软件库的源代码与您的目标类似。
以似乎是在切线中脱离的风险,我建议您在每个处理器基础上以单线实现fastcgi。
原因:
- 更健壮。
- 避免与多线程相关的上下文开关开销,并保护您免受并发僵局等问题。
- 避免进叉()成本(尽管相当轻巧)并保护您免于处理潜在的儿童僵尸程序以及其他头痛。
这将使您选择使用以下方式实现FastCGI接口:
- 非阻滞同步I/O (反应堆设计模式):阻止读取或写入请求,将请求传递给该请求适当的处理程序,然后阻止下一个请求。
- 异步I/O (ProCractor设计模式):将读取请求传递给O/S支持I/O的操作系统完成事件。在窗户上,这将是IO完成端口在Linux上,例如Epoll()。
- 接受线程 C++ 套接字中的函数循环
- 关于套接字通信的线程
- 用于线程间通信的 Windows 套接字
- 具有多线程应用程序的 Nanomsg 无阻塞双向套接字
- 套接字发送(.)线程的最佳数量
- 包含线程后C++套接字错误WSAENOTSOCK (10038)
- 多线程套接字编程服务器仅从 1 个客户端线程获取消息
- 每个线程或每个调用一个 ZeroMQ 套接字
- QSocketNotifier:不能从另一个线程启用或禁用套接字通知程序
- 使用Berkeley套接字的线程通知
- 在多线程HTTP服务器中发送后,如何干净地关闭套接字
- C /Linux:如何编写使用套接字的线程安全库
- windows DLL是否有可能在多个线程或进程之间使用相同的套接字编号
- c++系统()挂起,使用netcat连接到不同线程中的套接字
- 访问已传递给线程的套接字
- 提升同一对象上的异步套接字和线程池io_service
- zmq 套接字可以同时在两个线程中读取和写入吗?
- 从分离的线程中止套接字连接
- Unix 多播套接字线程安全吗?
- 最高效的高性能服务器套接字/线程设计