欢迎来到我们的多线程系列的第 2 部分!在第 1 部分中,我们探讨了原子性 和 不变性。
在这一部分中,我们将深入了解饥饿,因为它对于工程师来说至关重要,因为它确保了公平性和系统性能。通过认识饥饿风险,工程师可以设计优先考虑公平性、防止资源垄断并确保所有线程获得必要的 CPU 时间和资源以实现最佳运行的系统。
想象一下您正在玩在线多人游戏,并且您正在尝试加入流行游戏模式的大厅,例如团队战斗。你已经在大厅等待了一段时间,但每次比赛开始时,一批网速更快或技能排名更高的新玩家都会优先添加到游戏中。你看到比赛一遍又一遍地开始,但你似乎从来没有进去过!
从技术上讲,您已经在队列中,但由于响应时间更快或排名更高的其他玩家不断先进入游戏,因此您会无限期地留在大厅中。尽管拥有功能完美的系统,但由于匹配算法不公平地优先考虑其他人,您被剥夺了玩游戏的机会。
饥饿是指进程不断被拒绝访问其继续运行所需的资源,即使这些资源可用。该进程保持等待状态,因为较高优先级的进程或其他资源分配策略阻止它获取必要的资源。与死锁不同,资源并不是完全不可用,而是进程由于调度不公平而无法访问它们。
优先级反转:当较高优先级进程正在等待较低优先级进程所持有的资源时,如果其他较高优先级进程正在等待较低优先级进程的 CPU 时间,则较低优先级进程可能会缺乏 CPU 时间。进程不断到达。
资源分配策略:某些调度算法可能会偏向某些进程(通常是优先级较高的进程),导致优先级较低的进程很少被分配资源。
设计不佳的算法:如果资源分配算法不平衡或不公平,可能会导致某些流程不断被忽视。
高资源需求:如果少数进程需要过多的资源,它们可能会通过独占这些资源而导致其他进程挨饿。
等待时间长:经常被抢占或发现自己在竞争有限资源的进程可能会遇到饥饿。
Java 的 ReentrantLock 提供了一个强制公平的选项。通过使用带有 true 参数的 ReentrantLock 构造函数,我们可以确保线程以先来先服务 (FCFS) 的方式获取锁,从而防止饥饿。
private final Lock lock = new ReentrantLock(true); // Fair lock
信号量用于控制对有限数量资源的访问。通过使用启用公平性的信号量,我们可以确保线程以公平的顺序获取许可,避免饥饿。
private final Semaphore sp = new Semaphore(1, true); // Fair semaphore
Semaphore(1, true) 是一种只有一个许可且启用公平性的信号量。
在传统的生产者-消费者问题中,如果生产者压倒消费者或者消费者被拒绝访问共享资源,则可能会发生饥饿。 BlockingQueue 可以防止这种情况发生,因为它会自动处理生产者和消费者之间的同步。当队列已满或为空时,生产者和消费者分别被阻塞。这确保了两者之间的公平平衡,并防止其中一个压倒另一个,从而避免饥饿。
在多个任务被 fork 和 join 的场景中,Java 中的 ForkJoinPool 提供了一种在线程之间公平地平衡工作的方法。它确保工作窃取,防止活动较少的线程出现饥饿现象。 Java 的 ForkJoinPool 可以有效地处理任务分割和平衡,确保没有线程因工作而饿死。这是通过使用工作窃取算法来实现的,其中空闲线程从繁忙线程中窃取任务,以保持一切顺利进行
操作系统 (OS) 使用各种技术来避免饥饿,即由于较高优先级的任务占据主导地位,某些进程或线程长时间无法获得必要的资源(例如 CPU 时间、内存或 I/O 访问)的情况。以下是操作系统防止饥饿的一些常见方法:
No. | Method | Description | Prevents Starvation By |
---|---|---|---|
1 | Aging | Gradually increases priority of waiting processes. | Prevents long waits by adjusting priority based on wait time. |
2 | Round-Robin Scheduling | Allocates CPU time in a fixed cyclic order. | Ensures all processes get CPU time, avoiding starvation. |
3 | Completely Fair Scheduler | Allocates CPU based on fairness, independent of priority. | Ensures fair distribution of CPU time. |
4 | Priority Boosting | Temporarily raises the priority of starved processes holding important resources. | Prevents priority inversion and ensures high-priority tasks get needed resources. |
5 | Multilevel Feedback Queues | Dynamically adjusts process priorities based on behavior. | Promotes long-waiting processes to higher-priority queues. |
6 | Semaphores with Fairness | Ensures fair access to resources through FIFO queues. | Prevents low-priority tasks from being perpetually blocked by higher-priority tasks. |
7 | Fair Resource Allocation | Distributes system resources like CPU and memory based on process demand and need. | Prevents resource-hogging processes from starving others. |
8 | Fair I/O Scheduling | Prioritizes I/O requests to ensure timely completion for all processes. | Prevents disk I/O starvation for processes making low-priority requests. |
通过实施这些策略,操作系统可以确保没有进程或线程无限期地缺乏资源,从而促进更公平、更高效地使用系统资源。
非常感谢在线文档、社区和所有可用资源,使本文成为可能。
以上是多线程概念部分饥饿的详细内容。更多信息请关注PHP中文网其他相关文章!