同时运行两个线程

Posted

技术标签:

【中文标题】同时运行两个线程【英文标题】:Running two threads at the same time 【发布时间】:2013-10-19 21:32:48 【问题描述】:

我想知道一个程序是否可以(这基本上就是它的用途对吗?)。但是,如果我要在一个运行在线程 A 上的函数中进行系统调用,并在另一个运行在线程 B 上的函数中运行一些其他任务,它们是否能够同时运行或者我的第二个函数等到系统调用完成?

附加到我原来的问题:现在这个过程在系统调用进行时仍然是一个不可中断的过程吗?我说的是在 UNIX/LINUX 上使用任何系统调用。

【问题讨论】:

【参考方案1】:

多线程和并行处理是两个完全不同的话题,各有千秋,但为了介绍……

线程: 当您启动可执行文件时,它会在进程内的线程中运行。当您启动另一个线程时,将其称为线程 2,您现在在同一进程中有 2 个单独运行的执行链(线程)。在 single core microprocessor (uP) 上,可以运行多个线程,但不能并行运行。尽管从概念上讲线程通常在同一时间运行,但它们实际上是在操作系统分配和控制的时间片中连续运行。这些切片相互交错。因此,线程 1 的执行步骤实际上并不与线程 2 的执行步骤同时发生。这些行为通常会扩展到您创建的线程数,即执行链的数据包都在同一个进程中工作并共享时间由操作系统分配的切片。

因此,在您的 系统调用 示例中,它实际上取决于系统调用是什么,它是否会在允许其他线程的执行步骤继续进行之前完成。有几个因素会影响会发生什么:它是阻塞调用吗?一个线程是否比另一个线程具有更高的优先级。时间片的持续时间是多少?

与 C 中的 threading 相关的链接:SO ExamplePOSIXANSI C

并行处理: 当多核系统(多个 uP 或多个多核 uP)上发生多线程程序执行时,线程可以同时运行,或者并行,因为不同的线程可能被拆分到不同的内核以共享工作量。这是并行处理的一个示例。

再次,在概念上,并行处理和线程被认为是相似的,因为它们允许事情同时完成。但这只是概念,它们在目标应用和技术方面确实非常不同。线程作为一种在进程中识别和拆分整个任务的方法很有用(例如,当请求新连接时,TCP/IP 服务器可能会启动工作线程,然后连接并保持该连接,只要它仍然存在) ),并行处理通常用于将相同任务的较小组件(例如,可以在不同位置独立执行的一组复杂计算)发送到单独的资源(内核或 uP)到同时完成。这就是多核处理器真正发挥作用的地方。但并行处理也利用了多个系统,在 geneticsMMORPG 游戏等领域很流行。

与 C 中的并行处理相关的链接OpenMPMore OpenMP(示例)Gribble Labs - Introduction to OpenMPCUDA Tookit from NVIDIA

关于线程和架构一般主题的补充阅读:

这个线程和架构的总结几乎没有触及表面。这个话题有很多部分。解决他们的书籍将是fill a small library,还有thousands of links。毫不奇怪,在更广泛的主题中,一些概念似乎不符合理性。例如,it is not a given that simply having more cores will result in faster multi-threaded programs

【讨论】:

假设我们至少有两个处理器,是否存在任何系统调用可以使进程不受信号中断的情况,同时让我的其他函数运行?你说“关于它是否会在允许另一个线程的执行步骤继续之前完成”。这是在单个处理器中吗?因为多处理器允许两者使用线程同时运行,对吗?在单个处理器中它将是并发的,因此我的其他功能将不得不等待,这是您的意思吗? 规则随着多处理器/核心能力而改变。现在可以编写调用/程序来分解要在特定内核上执行的特定作业。是的,这将改变能够调用 blocking 函数的行为,而不是让它们停止主线程中的事情。关于这个主题有很多好帖子,including this one。 这个过程会是一个不可中断的过程吗?在系统调用期间 是的,您可以使用线程或(更好)将其拆分到另一个内核来编写无法解释的进程。可以提升线程的优先级。您正在使用的操作系统将发挥作用。如果您使用的是 Windows,则必须小心提高线程的 priority如果线程长时间以最高优先级运行,系统中的其他线程将无法获得处理器时间。 续:这可能会导致问题。实时操作系统或更好的外部硬件更适合某些任务,例如无需中断的快速数据采样。【参考方案2】:

是的,它们至少可能会“同时”运行,这正是线程的用途;当然还有很多细节,例如:

如果两个线程都运行系统调用,例如写入相同的文件描述符,它们可能会暂时相互阻塞。

如果使用互斥锁等线程同步原语,则并行执行将被阻止。

您需要一个至少有两个内核的处理器才能真正同时运行两个线程。

这是一个非常庞大且非常复杂的主题。

【讨论】:

系统调用是否会在系统调用进行时使进程成为不可中断的进程?在 UNIX/LINUX 中使用任何系统调用可以实现这一点吗? 这取决于系统调用(可能还有其他一些细节)。【参考方案3】:

如果您的计算机只有一个 CPU,您应该知道它如何同时执行多个线程。

在单处理器系统中,在给定时刻仅发生单个执行线程。因为单处理器系统支持逻辑并发,而不是物理并发。

在多处理器系统上,实际上是多个线程同时执行,并且实现了物理并发。

多线程程序的重要特点是支持逻辑并发,而不是实际是否实现物理并发。

【讨论】:

【参考方案4】:

基础很简单,但细节很快就会变得复杂。

你可以将一个程序分成多个线程(如果这样做有意义的话),每个线程将“按照自己的节奏”运行,这样如果一个人必须等待,例如,一些文件 I/O 不不要让其他人慢下来。

在单个处理器上,通过以某种方式对处理器进行“时间切片”来容纳多个线程——或者基于简单的时钟,或者让一个线程运行直到它必须等待(例如,等待 I/O)然后“切换”到下一个线程。为了最大限度地提高效率,需要一门艺术/科学。

在多处理器(例如大多数具有 2 到 8 个“核心”的现代 PC)上,每个线程都被分配给一个单独的处理器,如果没有足够的处理器,那么它们就像在单处理器情况下一样被共享.

确保单个线程操作的“原子性”以及确保线程不会以某种方式相互干扰的整个领域都非常复杂。一般来说,有一个“内核”或“核心”类别的系统调用不会被另一个线程中断,但这只是所有系统调用的一小部分,您必须查阅操作系统文档以了解哪个类别特定的系统调用落入。

【讨论】:

您能否在一个线程上启动系统调用并在另一个线程上接收另一个系统调用时已经在等待?还是等待也阻塞所有其他系统调用? 这取决于系统调用和系统。通常,对例如磁盘扇区的进程内请求不会阻止例如由不同线程进行的网络操作。但是个别操作系统有各种通常很愚蠢的限制。唯一的“权威”(如果有的话)是“官方”文档。【参考方案5】:

它们将同时运行,因为一个线程独立于另一个线程,即使您执行系统调用。

不过测试起来很容易,您可以创建一个线程来将某些内容打印到控制台输出,然后在另一个线程上执行系统调用,您知道这将花费一些合理的时间。您会注意到消息将继续由另一个线程打印。

【讨论】:

现在这个进程在系统调用过程中是否仍然是一个不可中断的进程? @user2644819 这至少取决于实际的系统调用和操作系统... 让我改写一下:在 UNIX/LINUX 上是否有任何系统调用可以实现这一点? “不间断”是什么意思?操作系统可以随时中断进程... 最后,您希望您的进程不符合被操作系统中断的条件吗?是这样吗?【参考方案6】:

是的,一个程序可以同时运行两个threads

它被称为Multi threading。

它们是否能够同时运行,或者我的第二个函数会等到系统调用完成吗?

它们都可以同时运行。


如果你愿意,你可以让线程 B 等到线程 A 完成或反转

【讨论】:

现在这个进程在系统调用过程中是否仍然是一个不可中断的进程? 应该没有必要,但是如果您的系统调用是send()recv() 类型调用,那么这将导致数据丢失。您可以使用信号中断系统调用。 我不想中断系统调用。我只是想知道它是否有可能在我的其他功能运行时进入一个不可中断的进程。 为什么所有的答案都说线程会同时运行?这实际上取决于情况(处理器数量、操作系统、被调用的函数等)。对于任意场景,它们将同时运行并不仅仅是给定的。【参考方案7】:

两个线程只有在多核处理器系统上才能同时运行,但如果它只有一个核处理器,则两个线程不能同时运行。所以一次只运行一个线程,如果它完成了它的工作,那么队列中的下一个线程需要时间。

【讨论】:

以上是关于同时运行两个线程的主要内容,如果未能解决你的问题,请参考以下文章

c++多线程同时运行两个函数该怎样编程啊?

Qt - 如何在不显式实现线程的情况下同时运行两个插槽

如何在 c++ winform 中同时运行两个函数?

c++线程异步同时运行

两个同时运行的线程控件(BackgroundWorker)串数据

Java之多线程详解