单个程序中的 10 个线程或 1 个线程程序运行 10 次(C++)?

Posted

技术标签:

【中文标题】单个程序中的 10 个线程或 1 个线程程序运行 10 次(C++)?【英文标题】:10 threads in a single program or 1 thread program ran 10 times (C++)? 【发布时间】:2020-01-17 10:23:08 【问题描述】:

我想知道在运行具有 10 个不同线程的单个程序 (exe) 或使用单个线程并行运行该程序 10 次(从 .bat 文件启动它)假设工作完成时,性能是否有任何差异是一样的,只是程序产生的线程数改变了吗?

我正在开发一个客户端/服务器通信程序,并想测试它的吞吐量。我目前正在学习并行编程和线程,因为不确定 Windows 将如何处理上述情况。调度程序在这两种情况下的工作方式是否相同?会有性能差异吗?

运行程序的机器有 4 个线程。

【问题讨论】:

不幸的是,程序通常不能并行化,以便所有工作负载可以均匀地分布在线程之间。考虑 i/o,如果程序需要来自文件的输入,则需要读取此输入 4 次(使用 4 个单线程)或以某种方式在线程之间共享输入 运行程序 10 次意味着你得到了 10 个进程。运行一个具有 10 个线程的程序意味着您将获得 1 个具有 10 个线程的进程。线程已被引入为“轻量级进程”,以降低并发执行的操作系统开销/负载。因此,理论上一个具有 10 个线程的进程可能会更快,但这当然取决于程序的实现方式以及线程是否可以在没有任何其他同步的情况下真正并发运行,而不是使用一个线程启动 10 个进程... 恐怕答案实际上取决于您的操作系统和处理器。在抽象层面上,我猜想线程共享相同的内存空间,因此您的处理器在上下文切换时不必重新映射它,但实际影响是任何人的猜测。 不仅仅是操作系统和处理器。还有运行时和程序本身。例如,垃圾收集器对十个进程的工作可能比单个进程更好。或者它可能是相反的。除了“线程被设计比进程更轻量级;有时这有助于提高性能,有时它会扼杀它”之外,还有太多的变量不能说。 @foreknownas_463035818 在大多数情况下,我会将相同的问题应用于多线程和进程。如果我找不到额外的 N 个线程可以有效地做的事情,那么额外的 N 个进程意味着什么? 【参考方案1】:

线程的重量比进程略轻,因为进程可以获取许多内容的副本。尤其是当您比较启动一个新线程和启动一个新进程所需的时间时(从头开始,fork 也可以避免很多成本)。尽管在任何一种情况下,您通常都可以在可能的情况下使用工作池获得更好的性能,而不是启动和停止新的进程/线程。

另一个主要区别是默认情况下线程都共享相同的内存,而进程拥有自己的内存并且需要通过更明确的方式进行通信(可能包括共享内存块)。这可能使线程解决方案更容易避免复制数据,但这也是多线程编程的危险之一,如果不注意它们如何使用共享内存/对象。

还可能有一些 API 更侧重于单个进程。例如,在 Windows 上有 IO Completion Ports,它基本上适用于对不同的文件、套接字等进行许多正在进行的 IO 操作,并使用多个线程(但通常远少于文件/套接字的数量)来处理结果因为它们通过GetQueuedCompletionStatus 循环可用。

【讨论】:

@bluiska 没问题。另外,我刚刚想到了 API 的使用会影响设计

以上是关于单个程序中的 10 个线程或 1 个线程程序运行 10 次(C++)?的主要内容,如果未能解决你的问题,请参考以下文章

多线程文件复制比多核CPU上的单个线程慢得多

如何同步线程中的 2 个进程以便它们一起运行?

Python多线程是啥意思?

线程学习知识点总结

查看主机CPU信息

线程小结一