Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 有没有过多的线?_C++_C_Multithreading_G++ - Fatal编程技术网

C++ 有没有过多的线?

C++ 有没有过多的线?,c++,c,multithreading,g++,C++,C,Multithreading,G++,环境:Ubuntu16.04-Linux,使用GCC编译C++11。软件不需要跨平台,但它的任务效率高,并且是一个优秀的守护进程 目前我有一个稍微简单的应用程序,它基本上充当第三方服务和websocket连接之间的中介。因此,用户通过websocket连接到我的服务,与上述第三方服务进行对话 | End-User | <-C1-> | My Application | <-C2-> | 3rd Party Service | |最终用户| |我的应用程序| |第三方服

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

目前我有一个稍微简单的应用程序,它基本上充当第三方服务和websocket连接之间的中介。因此,用户通过websocket连接到我的服务,与上述第三方服务进行对话

| End-User |  <-C1-> | My Application | <-C2-> | 3rd Party Service |
|最终用户| |我的应用程序| |第三方服务|
我的应用程序目前有2个主线程:

  • 线程1—侦听websocket连接,每当它收到消息时,就会将包含该消息的对象和请求该消息的websocket连接推送到fifo任务队列

  • 线程2-在消息队列中循环,弹出消息并对其进行处理

  • 问题是线程1非常快,可以轻松处理100个websocket连接。线程2有时会执行阻塞任务,速度可能会很慢,因为第三方服务处理某些队列项目需要一段时间。这意味着,如果用户a确实请求1(响应时间为5秒),则随后发出请求2的用户B将不得不等待用户a的请求1完成,即使请求2的响应时间小于1ms

    我提出的解决方案是:

    • 线程1-WebSocket连接侦听器
    • 线程2任务委托器
    • 线程3-100-任务工作者
    线程1可以轻松处理100个websocket连接,每个连接都可以发出任务请求,所需时间在1毫秒到1分钟之间。所有的3-100线都在睡觉。产生这么多线程的原因是,如果有50-60个连接都发出不同的长时间运行请求,而这些耗时的调用中的每一个都只阻塞一个线程,那么其他线程仍然可以自由地处理队列和执行其他任务

    我知道切换线程是一项密集型操作,但除了mulithreading之外,我不知道还有其他方法

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

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


    有没有过多的线

    100条线

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

    其他战略

    为了获得最大吞吐量,通常的设计决策是每个cpu核~1个线程,采用基于异步反应器的设计

    一些例子:

    • 利伯夫

    • boost::asio

    • libdispatch

    • win32异步操作

      • “是否存在线程过多的问题?”-是的。线程消耗可能耗尽的系统资源。线程需要调度;需要内核的工作以及CPU上的时间(即使他们决定什么都不做)。更多的线程会增加复杂性,使程序更难推理和调试


        确实存在这样一种情况:线程太多-永远不要创建超出您需要的线程/对您的程序有意义的线程。

        最简单、可能也是最有效的方法是使用线程池。线程池通常由操作系统(或.NET等底层平台)实现,并针对最佳吞吐量进行了优化。线程池持续监视发送到线程池的任务的执行效率,并在吞吐量下降时动态创建新线程,或者在一段时间内无事可做时释放线程。创建和释放线程的算法非常复杂,在大多数情况下,线程池是将工作负载拆分为多个线程的最有效方法


        Windows和Linux都支持线程池,但是既然使用C++ 11,也可以使用标准的C++库线程池,可以调用函数<代码> STD::AsYNC/<代码>。这里有一些不错的。

        你可以用完手柄,是的。此外,(活动)线程的数量应与可用CPU内核的数量相平衡。您可能希望查找线程池。线程的数量不会成为问题:另一个有效组织消息队列的好方法是ZeroMQ。线程使用有限的系统资源,所以总是有可能有太多的线程。限制取决于系统。无论如何,您的想法与称为“线程池”的软件设计模式有很多共同之处。如果主机系统支持它,您可能需要考虑使用异步I/O。每个CPU的1线程对于CPU瓶颈任务来说是很好的;但当这个问题受到IO约束时,它就变得模糊多了。我曾经在一个应用程序中使用过100个线程,这些线程只是执行ping任务;因为线程通常处于阻塞函数中,等待网络数据。@UKMonkey这是基于reactor的设计试图缓解的问题。但是,是的,我们都经历过……我认为ZeroMQ方法值得一提。特别是当涉及到MQ设计模式(如reactor)时,需要考虑一些重要的事情:POSIX异步IO(顺便说一下,它使用Linux下的线程),select/poll/epoll,如果非阻塞socketsThreads没有准备好/正在运行,则不需要对其进行调度。我发布这篇文章的盒子管理着1044个ATM线程。没问题。CPU目前使用的是2%%,(UTRORAND和Firefox,大多数)。@ Martin James当然可以,但内核仍然需要考虑它们。它们仍然在跑步队列中占据一席之地