与并发相关的Bug类型
与并发直接相关的Bug主要分为两大类:非预期的阻塞(Unwanted blocking) 和 竞态条件(race condition).
Unwanted blocking
不希望的阻塞是指线程在等待某件事情(如互斥锁、条件变量、未来值或I/O操作)时无法继续执行,而这种等待是不必要的或是有害的(不符合对当前线程的设计 )。
不希望的阻塞会让其他等待当前被阻塞的线程也被阻塞。
不希望的阻塞通常发生在以下几种情况:
- 死锁(deadlock):
- 当两个或更多线程相互等待对方释放资源时,形成一个循环依赖,导致所有涉及的线程都无法继续执行。
- 最明显的情况是,如果负责用户界面的线程死锁,界面将失去响应。
也有一些情况是,界面可以保持响应,但一些任务无法完成,比如搜索不返回结果,或者文档不被打印。
- 活锁(livelock):
- 与死锁类似,但涉及的是非阻塞等待,如自旋锁。
线程在循环中主动检查条件,但由于某种原因(如调度问题),条件始终不满足,导致线程无法继续执行有用的工作。 - 其表现的症状就和死锁一样,比如程序不进行,此外由于线程仍在运行,CPU 会处于高使用率状态。
在不太严重的情况下,活锁最终会被操作系统的随机调度解决,但仍然会造成任务的长时间延迟,并且延迟期间 CPU 使用率很高。
- 与死锁类似,但涉及的是非阻塞等待,如自旋锁。
- I/O 阻塞或其他外部输入:
- 线程在等待外部输入(如网络数据、文件读取等)时无法继续执行。如果这种输入永远不会到来,线程将无限期地阻塞,从而浪费系统资源。