优先级反转:
在t5时刻T1还是等待T3,但是这时候T2进来了,T1就是要等T2了
共享资源:在此处两个进程的共享资源就是变量i
临界区:进程在访问共享资源的时候
互斥:进程在访问 共享资源只有一个进程处于临界区,没有其他进程同样处于临界区
死锁:两个或以上的进程在相互等待完成特定任务,最终谁也完成不了
饥饿:一个可执行的进程,被调度器持续忽略,以至于虽然处于可执行状态却不被执行;
生活中的一个例子可以是:假设有一个单独的浴室供家庭中的多个人使用。在这个浴室中,洗漱区域(例如洗手盆、镜子、洗漱用品等)可以被认为是一个临界区。因为只有一个人可以同时使用这些资源,否则可能导致混乱或不便。
在这个例子中,如果一个人正在使用洗手盆洗漱,那么其他人必须等待他完成之后才能使用。这样可以避免多个人同时使用洗漱区域,造成拥挤或者资源冲突。
通过这种限制,我们可以确保每个人都有充分的时间和空间来完成洗漱,而不会因为多人同时使用而导致混乱。这类似于在计算机程序中实现临界区的思想,即确保在任意时刻只有一个线程或进程可以访问共享资源,以防止数据竞争和不一致性。
在浴室的例子中,可以将锁类比为一种管理访问洗漱区域的机制。锁就像是浴室门上的锁,只有持有钥匙的人可以打开门进入洗漱区域,其他人必须等待这个人使用完毕并释放钥匙后才能进入。
这里,洗漱区域可以被认为是临界区,因为在同一时间只能有一个人进入并使用。当一个人持有锁(钥匙)时,表示他正在访问临界区,其他人必须等待直到他释放锁(归还钥匙)后才能访问。
因此,锁的作用就是确保在任何时刻只有一个人可以进入临界区,防止多个人同时访问导致的混乱或资源冲突。这与计算机编程中锁的概念类似,锁用于保护临界区,确保在同一时间只有一个线程或进程可以访问共享资源,从而避免数据竞争和不一致性问题。
临界区的长度通常不是任意可变的,而是由程序设计和需求决定的。在实际开发中,设计者会努力控制临界区的长度,以保证程序的性能和正确性。
然而,有时候确实可能会出现临界区较长的情况,特别是在处理复杂的操作或对大量数据进行处理时。在这种情况下,可以尝试以下方法来管理临界区的长度:
分解临界区: 如果可能的话,将较长的临界区分解成多个较小的临界区,这样可以减少多个线程或进程之间的竞争,提高并发性能。
优化临界区内的操作: 对临界区内的操作进行优化,使其尽可能地高效。这可能包括减少不必要的计算或IO操作,以缩短临界区的执行时间。
减少临界区内的竞争: 考虑使用更细粒度的锁或其他同步机制,以减少多个线程或进程之间的竞争。这样可以在临界区内允许更多的并发访问。
异步处理: 如果可能的话,考虑使用异步处理来减少临界区的长度。将一些长时间运行的操作移出临界区,在后台异步执行,以避免阻塞其他线程或进程。
总的来说,虽然临界区的长度可能会根据具体情况变长,但是在实际开发中,我们通常会尽量控制临界区的长度,以确保程序的性能和正确性。
锁
例子:两个人因为时间的差异,却做了相同的事情