【发布时间】:2016-06-11 20:13:48
【问题描述】:
在同步/阻塞计算模型中,我们通常说执行线程会在等待 IO 任务完成时等待(阻塞)。
我的问题是这通常会导致执行线程的 CPU 内核空闲,还是等待 IO 的线程通常会被上下文切换并进入等待状态,直到 IO 准备好被处理?
【问题讨论】:
标签: multithreading asynchronous blocking synchronous cpu-architecture
在同步/阻塞计算模型中,我们通常说执行线程会在等待 IO 任务完成时等待(阻塞)。
我的问题是这通常会导致执行线程的 CPU 内核空闲,还是等待 IO 的线程通常会被上下文切换并进入等待状态,直到 IO 准备好被处理?
【问题讨论】:
标签: multithreading asynchronous blocking synchronous cpu-architecture
对于大多数以标准方式使用的编程语言,答案是它会阻塞你的线程,但不会阻塞你的 CPU。
您需要为 1 个线程显式地为特定线程(亲和性)保留一个 CPU 以阻塞整个 CPU。要更明确,请参阅此question:
您可以在除您的进程之外的每个进程上调用 SetProcessAffinityMask,并使用一个掩码,该掩码仅排除将“属于”您的进程的核心,并在您的进程中使用它来将其设置为仅在该核心上运行(或者,甚至更好, SetThreadAffinityMask 仅在执行时间关键任务的线程上)。
【讨论】:
CPU 内核通常不专用于一个特定的执行线程。内核不断地切换正在执行的进程进出 CPU。 CPU当前正在执行的进程处于“运行”状态。等待轮到它们的进程列表处于“就绪”状态。内核非常快速地切换这些输入和输出。现代 CPU 功能(多核、同时多线程等)试图增加可以一次物理执行的执行线程数。
如果一个进程被 I/O 阻塞,内核只会将它放在一边(将其置于“等待”状态),甚至不会考虑在 CPU 中给它时间。当 I/O 完成后,内核将阻塞的进程从“等待”状态移动到“就绪”状态,以便它可以在 CPU 中轮到(“运行”)。
所以你阻塞的执行线程只会阻塞:执行线程。 CPU 和 CPU 内核继续让其他执行线程进出它们,并且不会空闲。
【讨论】:
如果我们假设它不是异步的,那么我会说,在这种情况下,拥有该线程的线程肯定会被放入等待队列,并且状态将是“等待”。
上下文切换明智,IMO,它可能需要更多解释,因为术语上下文切换可能意味着/涉及许多事情(换入/换出、页表更新、寄存器更新等)。根据当前的执行状态,可能会安排属于同一进程的第二个线程运行,而在 IO 操作上被阻塞的线程仍在等待。
例如,上下文切换很可能仅限于更改 CPU 上与内核有关的寄存器值(但如果剩余内存不多,拥有的进程甚至可能被换出)。
【讨论】:
不,在java中,块线程不参与调度
【讨论】: