【问题标题】:maximum number of threads - How to determine if your C++ pthreads are running in parallel?最大线程数 - 如何确定您的 C++ pthreads 是否并行运行?
【发布时间】:2018-05-02 13:43:32
【问题描述】:

我对多线程编程的了解不够。在我的 C++ 程序中,我创建了 10 个 pthread,每个 pthread 负责处理流向系统的实时数据的一部分。最终在 main() 内部,来自所有线程的处理过的数据被合并。据我所知,可以并行运行的线程的确切数量由每个插槽的核心数 x 每个插槽的线程数 x 插槽决定,在我的例子中是 8 (4 x 2 x 1)。那么在我的具有 10 个线程的应用程序中,是否没有发生颚化,并且在不同线程之间交换是调度程序所做的事情?如果没有,有什么方法可以确定吗?或者至少我可以知道这种交换需要多少毫秒?由于我的应用程序正在处理实时数据,因此确保所有线程并行运行至关重要。

【问题讨论】:

  • 自 50 或 60 年前发明多任务处理以来,不同执行线程之间的“交换”一直在发生。如果您的系统支持 8 个并发线程,则需要进行此类交换。并且这种交换还包括在您的系统上运行的所有其他程序及其进程和线程。
  • std::thread::hardware_concurency 您可能会感兴趣。

标签: c++ parallel-processing pthreads


【解决方案1】:

“据我所知,线程的确切数量......”

一种——还有超线程可以处理事情;还有一个事实是 C++ 可以在非 PC 上运行。 (即嵌入式设备)将具有静态编号。

“是调度器做什么”

是的。但不仅仅是你的线程;操作系统和其他应用程序的所有线程也受此控制。

或者至少我可以知道这个交换需要多少毫秒

没有;也没有关系,因为你对此无能为力。您能做的最好的事情是尝试跟踪您的线程上有多少 CPU 时间,计算出单个线程可用的总 CPU 时间;然后你可以算出你有多少时间;但同样,您永远不需要这样做,因为这可能意味着您的程序正在担心它无法控制的事情。更有意义的是监控机器的 CPU 使用率。

由于我的应用程序正在处理实时数据,因此它对 确保所有线程都在并行运行。

线程如何运行并不取决于您;这取决于操作系统。您的计算机上还有其他比程序更重要的任务。例如,操作系统需要处理时间来处理应用程序对内存的任何请求。

有些操作系统实际上能够以更专业的方式做到这一点;例如 Qnix 是一个实时操作系统;但这需要付出其他代价。

有一点你可以确定;是,如果您的最大可能线程数为 8;你创造了 10 个;您不会让它们全部并行运行。您可能希望查看一些有助于确保您创建的线程始终处于忙碌状态的库;以boost::asio 为例

【讨论】:

  • 感谢您的完整回答!所以按照你说的,即使我有 8 个线程,它们也不会是并行的,因为操作系统不仅仅处理我的程序......
  • 它们可能会在某个时候并行;而且它们在某些时候也可能不会并行。这就是线程同步如此重要的原因。
  • 在C++中使用timeval等结构并计算每个线程内的时间是否正确?基本上,我的应用程序中的每个线程所做的是创建和打开一个 UDP 套接字,并在 while 循环内的特定端口上侦听来自其他 linux 机器的实时数据。
  • @AliNouri stackoverflow.com/questions/44916362/… 请记住:1.您的线程可以随时进行上下文切换。包括在获取任何时间信息之前/之后。 2.如果线程被阻塞(例如在read()中);然后操作系统会将其关闭。
  • 在 Linux 上;你可以改变一个进程和它的线程的“niceness”(man nice),这将鼓励操作系统给你的线程处理时间超过其他线程。
【解决方案2】:

我还不能添加 cmets,所以作为答案的一部分。

或者至少我可以知道这个交换需要多少毫秒

在 Windows 上,这是默认值 10 - 20 毫秒 通过一个小技巧,您可以将其更改为 1 - 2 ms

#include <Mmsystem.h>
#pragma comment(lib,"winmm.lib")
timeBeginPeriod(1); // set system clock to 1ms from default 10ms

如果您想添加另一个肮脏的技巧来赋予您的流程更多的权力。 您需要在 main() 进程中添加以下 2 行,并且您还需要为每个线程执行此第 2 行。

SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);

警告!!!! 如果您使用比处理核心更多的线程执行此操作,您将使窗口无响应。所以你需要在线程中给系统一些时间。

在 Linux 上,默认值已经是 1 毫秒(动态),但您可以在不同的调度程序之间进行更改。

【讨论】:

  • timeBeginPeriod 改变时钟的分辨率;它不会影响交换需要多长时间;这肯定远不及 1ms
  • 它改变了中断需要多长时间才能重新安排。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-14
  • 2011-12-16
  • 1970-01-01
  • 1970-01-01
  • 2010-10-26
相关资源
最近更新 更多