c++ - 有没有线程太多这样的事情?

标签 c++ c multithreading g++

环境:Ubuntu 16.04 - Linux,使用 GCC 编译 C++11。软件不需要是跨平台的 - 但它的任务高效,并且是一个优秀的守护进程。

目前我有一个比较简单的应用程序,它基本上充当第三方服务和 websocket 连接之间的中介。因此用户通过 websocket 连接到我的服务以与所述第三方服务交谈。

| End-User |  <-C1-> | My Application | <-C2-> | 3rd Party Service |

我的应用程序目前有 2 个主线程:

  1. 线程 1 - 监听 websocket 连接,每当它收到消息时,它都会将一个对象推送到 fifo 任务队列,该对象包含该消息和请求该消息的 websocket 连接。

  2. 线程2 - 循环消息队列,弹出消息并处理

问题是线程 1 非常快,可以轻松处理 100 个 websocket 连接。线程 2 有时会阻塞任务并且可能会很慢,因为某些队列项目处理需要一段时间才能由所述第三方服务完成。这意味着,如果用户 A 确实请求 1,这需要 5 秒来响应,那么随后来并发出请求 2 的用户 B 将不得不等待用户 A 的请求 1 完成,即使请求 2 花费的时间少于 1 毫秒。

我建议的解决方案是:

  • 线程 1 - WebSocket 连接监听器
  • 线程 2 任务委托(delegate)者
  • 线程 3 - 100 - 任务 worker

线程 1 可以轻松处理 100 个 websocket 连接,每个连接都可以发出任务请求,耗时在 1 毫秒到 1 分钟之间。所有线程 3 - 100 都在休眠。这么多线程的原因是因为如果有 50-60 个连接都发出不同的长时间运行的请求,那么每个这些耗时的调用只会阻塞一个线程,其他线程仍然可以在队列上工作,并且做其他任务。

我知道切换线程是一项密集型操作,但我不知道这里除了多线程还有其他方法。

我已经用单线程解决了同样的问题 - 但问题是服务器在等待第三方服务阻塞时停止处理任何 websocket 消息。所以我把它增加到两个线程——一个用于 websocket,另一个用于处理任务队列。但现在的问题是任务队列中的单个工作人员速度很慢,因为它是按顺序处理阻塞 IO 操作。

这听起来像是一个糟糕的设计理念吗?对最佳做法有什么想法吗?

最佳答案

Is there such a thing as too many threads?

100 threads

应该没问题,如果在任何桌面/服务器上都不太理想。我有一台笔记本电脑在一个进程中约 2000 个线程后拒绝继续。

Other strategies

对于最大吞吐量,一个常见的设计决策是使用基于异步 react 器的设计,每个 cpu 核心约 1 个线程。

一些例子:

  • libuv

  • boost::asio

  • 库调度

  • win32 异步操作

关于c++ - 有没有线程太多这样的事情?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48747674/

相关文章:

c++ - 使用来自 streambuf 的 boost::asio::ip::tcp 将数据部分写入 TCP 套接字

c - C语言中的百分比

将 char 数组转换为 atoi 失败

c++ - OpenCV : 中缺少三角测量库

c++ - OpenCV:找到旋转点的原始坐标

c++ - 在 make 文件中链接 g++ 和 lib 不起作用

c - OpenMP线程,如何正确使用omp原子子句?

java - 为什么有时在 Maven 中测试期间 public static AtomicBoolean 变量为 false?

c++ - 如何以编程方式从 C/C++ 代码中获取当前可用的内存量?

c# - WCF webservice - 使用锁会导致问题吗?