type
status
date
slug
summary
tags
category
icon
password
Property
Sep 5, 2023 12:14 PM

阻塞

如果线程的执行由于某种原因导致暂停,那么就认为该线程被阻塞了
例如在Sleep或者通过Join等待其他线程结束
被阻塞的线程会立即将其处理器的时间片生成给其他线程,从此就不再小号处理器时间,直到满足其阻塞条件为止。
直到满足其阻塞条件为止:直到满足这个阻塞条件,处理器的时间片就回到本线程了,然后就可以继续消耗处理器的时间。
可以通过ThreadState这个恶属性来判断线程是否出于被阻塞的状态:
notion image

ThreadState

ThreadState是一个flags enum,通过按位的形式,可以合并数据的选项
notion image
运行状态的变化图
notion image
但是大部分的枚举值都没什么用,下面的代码将ThreadState剥离为四个最有用的值之一:Unstarted,Running,WaitSleepJoin,Stopped
notion image
ThreadState属性可用于诊断的目的,但不适用于同步,因为线程状态可能会在测试ThreadState和对该信息进行操作之间发生变化。

接触阻塞 Unblocking

当遇到下列四种情况的时候,就会解除阻塞
  1. 阻塞条件被满足
  1. 操作超时(如果设置超时的话)
  1. 通过Thread.Interrupt()进行打断
  1. 通过Thread.Abort()进行中止

上下文切换

当线程阻塞或解除阻塞时,操作系统将执行上下文切换。这回产生少量开销,通常为1~2微秒。

I/O-bound vs Computed-bound (或CPU-Bound)

一个花费大部分时间等待某事发生的操作称为I/O-bound
I/O绑定操作通常设计输入或输出,但这不是硬性要求:Thread.Sleep()也被视为I/O-bound。(干等着)
相反,一个花费大部分时间执行CPU密集型工作的操作称为Computed-bound

阻塞vs忙等待(自旋)Blocking vs Spinning

I/O-bound操作的工作方式有两种
在当前线程上的同步的等待
Consoe.Readline() Thread.Sleep() Thread.Join()
异步的操作,在稍后操作完成时触发一个回调动作。
同步等待的I/O-bound操作将大部分时间花在阻塞线程上
他们也可以周期性的在一个循环里进行“打转(自旋)”
notion image
notion image

在忙等待和阻塞放慢有一些细微差别

首先,如果您希望条件很快得到满足(可能在几微秒之内),短暂自旋可能会 很有效,因为它避免了上下文切换的开销和延迟
.NET Framework提供了特殊的方法和类来提供帮助SpinLock和SpinWait
其次,阻塞也不是零成本。这是因为每个线程在生存期间会占用大约1MB的内存,并会给CLR和操作系统带来持续的管理开销
因此,在需要处理成百上千个并发操作的大量I/O-bound程序的上下文中,阻塞可能会很麻烦
所以。此类程序需要使用基于回调的方法,在等待时完全撤销其线程
C#异步编程-02 Thread Join Thread SleepC#异步编程-04 什么是线程安全
  • Waline
Kitety
Kitety
独特为佳
公告
我曾经七次鄙视自己的灵魂
--卡里·纪伯伦
第一次,当它本可进取时,却故作谦卑;
第二次,当它在空虚时,用爱欲来填充;
第三次,在困难和容易之间,它选择了容易;
第四次,它犯了错,却借由别人也会犯错来宽慰自己;
第五次,它自由软弱,却把它认为是生命的坚韧;
第六次,当它鄙夷一张丑恶的嘴脸时,却不知那正是自己面具中的一副;
第七次,它侧身于生活的污泥中,虽不甘心,却又畏首畏尾。
 
最新评论
Loading...