操作系统之哲学原理第2版邹恒宇课后习题第三章答案(三) 您所在的位置:网站首页 自动控制理论邹伯敏第四版 操作系统之哲学原理第2版邹恒宇课后习题第三章答案(三)

操作系统之哲学原理第2版邹恒宇课后习题第三章答案(三)

2023-06-02 15:31| 来源: 网络整理| 查看: 265

目录

1.你能否用加载和存入原子指令实现锁?请给出答案。

2.在图10-1所示的锁的实现中,enable interrupts和disable interrupts两条指令紧邻似乎是无聊之举,因为它们 的效果相互取消。真的是这样吗?

3.一同学认为用在切换时将中断保持为禁止状态(见图10-9)的办法来解决图10-7所面临的问题太过复杂, 不如干脆将图10-7中的切换语句删除,留待操作系统的调度程序进行切换。这样就不存在在何处启用中断的 难题。即将上锁程序变为如下: lock(){ disable interrupts; if(value==FREE){ value=BUSY; }else{ add thread to queue of threads waiting for this lock; } enable interrupts; } 请问,上述锁的实现是否可行。如果可行,证明其可行性。如果不可行,给出反例。

4.一同学提出一个解决使用测试与设置指令、非繁忙等待实现锁时(见图10-10)所面临的一个线程同时存 在两个状态的问题。该方法非常简单,即让操作系统调度器在取得控制权后,检查一下刚刚被中断的线程是 否在锁的系统调用里面。如果是,则不予切换线程,即将控制权再交回给被中断线程,使其可以继续执行下 一句指令,从而切换到别的线程。请问这种方法能够奏效吗?如果能,它有什么缺点?如果不能,它存在什 么问题?

5.本章论述的锁的实现机制能否应用到多计算机环境?给出你的理由。

6.调研任意一款商用操作系统的锁的实现机理,并与本章内容进行比较,你能得出何种结论?

你如何看待上文所说的上下文切换,这个更通俗的说,是什么意思呢?

所以说,信号量和锁还不是一个东西?

1.你能否用加载和存入原子指令实现锁?请给出答案。

可以使用加载和存储原子指令来实现锁,常见的一种实现是使用比较和交换(Compare-and-Swap)指令。下面是一种基于比较和交换指令的简单锁实现示例:

lock = 0 # 初始状态锁为未锁定状态 def acquire_lock(): while True: # 尝试原子地将锁的状态从未锁定改为锁定状态 old_value = atomic_compare_and_swap(lock, 0, 1) if old_value == 0: # 成功获得锁 break def release_lock(): # 将锁的状态设置为未锁定状态 atomic_store(lock, 0)

2.在图10-1所示的锁的实现中,enable interrupts和disable interrupts两条指令紧邻似乎是无聊之举,因为它们 的效果相互取消。真的是这样吗?

在图10-1所示的锁的实现中,enable interrupts和disable interrupts两条指令的确是相互取消的,它们的目的是为了保护临界区代码的执行。虽然看起来似乎是无聊之举,但实际上这两条指令在特定的上下文中才具有意义。

当临界区代码需要保护共享资源免受并发访问时,disable interrupts指令可以阻止中断的发生,从而避免其他中断处理程序干扰临界区的执行。这样可以确保在临界区执行期间,不会发生其他中断或中断处理程序的执行。

在禁用中断期间,如果有其他线程或进程试图访问临界区,它们会被阻塞,直到中断被重新启用。而在临界区代码执行完毕后,通过enable interrupts指令重新启用中断,允许其他中断发生,并使被阻塞的线程或进程有机会进入临界区。

尽管这两条指令看起来是相互取消的,但它们在临界区代码的执行期间提供了一种保护机制,确保了临界区的独占性。它们的目的是为了确保临界区的完整性和一致性,而不受其他并发执行的干扰。

需要注意的是,在实际编程中,应该谨慎使用中断禁用,因为过度的中断禁用可能会影响系统的响应性能。因此,需要根据具体的应用场景和需求来评估是否需要使用中断禁用来实现临界区保护。

3.一同学认为用在切换时将中断保持为禁止状态(见图10-9)的办法来解决图10-7所面临的问题太过复杂, 不如干脆将图10-7中的切换语句删除,留待操作系统的调度程序进行切换。这样就不存在在何处启用中断的 难题。即将上锁程序变为如下: lock(){ disable interrupts; if(value==FREE){ value=BUSY; }else{ add thread to queue of threads waiting for this lock; } enable interrupts; } 请问,上述锁的实现是否可行。如果可行,证明其可行性。如果不可行,给出反例。

上述锁的实现是不可行的。虽然删除了图10-7中的切换语句,但仍然存在一个关键问题:在禁用中断期间,无法判断共享资源是否已经被其他线程或进程占用。

考虑以下情况:假设有两个线程A和B,都试图获取同一个锁,并且此时锁的value值为FREE。线程A首先执行到lock()函数,禁用了中断,然后执行到判断语句if (value==FREE),由于value为FREE,线程A进入临界区,将value设置为BUSY。此时,线程A被抢占,线程B获得CPU控制权。

由于中断被禁用,线程B无法执行判断语句if (value==FREE),也无法判断锁的状态。线程B无法得知锁已经被线程A占用,所以它会错误地将自己加入等待锁的线程队列,并启用中断。

此时,线程A完成临界区的操作后,解锁并离开。由于线程B已经在等待锁的线程队列中,而且中断被启用,线程B会被调度执行。然而,由于线程B在等待锁期间无法得知锁的状态,它会错误地认为锁处于FREE状态,进而进入临界区,造成多个线程同时进入临界区的情况,破坏了互斥性。

因此,上述锁的实现不可行,无法确保临界区的互斥性。在实现锁的过程中,需要通过禁用中断来保护临界区的执行,同时需要在合适的时机启用中断来允许其他线程或进程的访问和调度。这样才能保证锁的正确性和可靠性。

4.一同学提出一个解决使用测试与设置指令、非繁忙等待实现锁时(见图10-10)所面临的一个线程同时存 在两个状态的问题。该方法非常简单,即让操作系统调度器在取得控制权后,检查一下刚刚被中断的线程是 否在锁的系统调用里面。如果是,则不予切换线程,即将控制权再交回给被中断线程,使其可以继续执行下 一句指令,从而切换到别的线程。请问这种方法能够奏效吗?如果能,它有什么缺点?如果不能,它存在什 么问题?

这种方法是不可行的。虽然该方法看起来简单,即在操作系统调度器获得控制权后检查中断的线程是否在锁的系统调用内,并决定是否切换线程。然而,这种方法存在以下问题:

频繁的上下文切换:由于每次中断时都需要检查中断的线程是否在锁的系统调用内,这将导致频繁的上下文切换。即使一个线程在临界区的执行时间非常短暂,仍然会触发上下文切换,增加系统开销和延迟。

无法保证公平性:由于上下文切换是基于中断的线程是否在锁的系统调用内来决定的,这种方法无法保证所有等待获取锁的线程都有机会获得执行权。可能会出现某些线程长时间等待的情况,导致饥饿问题。

对操作系统调度器的依赖:这种方法依赖于操作系统调度器的实现方式,要求调度器能够正确地检测线程是否在锁的系统调用内。这增加了调度器的复杂性和对特定环境的依赖性。

综上所述,尽管该方法在理论上可能解决了线程同时存在两个状态的问题,但实际上它引入了更多的问题,包括频繁的上下文切换、公平性问题和对调度器的依赖。因此,这种方法并不可行,并不是一个有效的解决方案。在实现锁的过程中,需要采用合适的技术和算法来确保锁的正确性和可靠性,并解决可能出现的问题。

5.本章论述的锁的实现机制能否应用到多计算机环境?给出你的理由。

本章论述的锁的实现机制主要是基于单个计算机系统的上下文切换和中断机制。这些机制是在单个计算机系统内部进行的,涉及到对内存和寄存器的访问以及对中断信号的处理。因此,这种锁的实现机制不能直接应用到多计算机环境。

在多计算机环境下,涉及到多台计算机之间的通信和协调。多计算机环境通常采用分布式系统或集群系统的架构,其中每台计算机都具有自己的内存和处理器。在这种情况下,锁的实现需要考虑更复杂的通信和同步机制。

在多计算机环境中,常见的锁实现包括分布式锁、互斥锁、共享锁等。这些锁的实现通常涉及到网络通信、分布式协议、一致性算法等技术。多计算机环境下的锁需要考虑并发访问和数据一致性的问题,并确保各个计算机之间的同步和协调。

因此,尽管本章所述的锁的实现机制在单个计算机系统中是有效的,但在多计算机环境中需要使用特定的分布式锁机制或其他相关技术来实现并发控制和同步。

6.调研任意一款商用操作系统的锁的实现机理,并与本章内容进行比较,你能得出何种结论?

商用操作系统通常采用复杂而多样化的锁实现机制,以提供高效的并发控制和同步。这些实现机制可能会根据操作系统的设计和用途而有所不同。以下是一些常见的商用操作系统锁实现机制:

互斥锁(Mutex):互斥锁是一种常见的锁实现机制,用于确保只有一个线程或进程可以访问共享资源。商用操作系统中的互斥锁通常基于原子操作、自旋锁、或者更复杂的算法来实现。

读写锁(Read-Write Lock):读写锁允许多个线程同时读取共享资源,但只允许一个线程进行写操作。商用操作系统中的读写锁实现通常结合了互斥锁和条件变量等机制,以提供高效的读取和写入操作。

自旋锁(Spin Lock):自旋锁是一种忙等待的锁实现机制,线程在获取锁之前会一直自旋,不会主动让出CPU。这在多核系统上可以提高性能,但对于单核系统可能会导致浪费CPU资源。

信号量(Semaphore):信号量是一种用于线程同步和互斥的机制,用于限制同时访问共享资源的线程数量。商用操作系统中的信号量实现通常基于原子操作和队列等数据结构。

其实从第四题我就可以懂得,原来这里还是会执行类似于时间片的东东,就是我虽然手上有锁,但是我也很有可能一次执行不完我手上的内容,因此,要总是去抢这个资源。

你如何看待上文所说的上下文切换,这个更通俗的说,是什么意思呢?

上下文切换是指在多任务操作系统中,当操作系统需要切换执行不同的任务(线程或进程)时,需要保存当前任务的执行状态(也称为上下文),包括程序计数器、寄存器内容、内存映射等,并加载下一个任务的执行状态,以便能够从切换点继续执行。简单来说,上下文切换是从一个任务切换到另一个任务的过程。

在多任务系统中,操作系统通过分配时间片给不同的任务来实现任务的并发执行。当一个任务的时间片用完或发生某种事件(如等待I/O操作完成)时,操作系统会暂停当前任务的执行,并将执行权转移到另一个任务上。这个转移的过程就是上下文切换。操作系统会保存当前任务的执行状态,以便下次切换回来时可以继续执行。

上下文切换是一项开销较大的操作,因为它涉及到保存和恢复任务的执行状态,以及切换任务的开销(如刷新缓存、更新内存映射等)。频繁的上下文切换会导致系统性能下降,增加系统开销和延迟。

因此,在设计和实现操作系统时,需要权衡上下文切换的频率和开销。合理的任务调度策略和优化手段可以减少上下文切换的次数,提高系统的性能和响应能力。

所以说,信号量和锁还不是一个东西?

对的,信号量和锁是并发编程中两个不同的概念。

信号量(Semaphore)是一种用于线程同步和互斥的机制。它可以控制对共享资源的访问数量。信号量有一个计数器,线程可以通过执行P操作(等待)和V操作(释放)来对信号量进行操作。P操作会将信号量计数器减一,如果计数器为负,则线程会被阻塞。V操作会将信号量计数器加一,如果有线程在等待该信号量,则会唤醒其中一个线程。

锁(Lock)是一种用于确保共享资源的互斥访问的机制。它提供了两个基本操作:获取锁和释放锁。一次只有一个线程可以成功获取锁,其他线程必须等待。当线程持有锁时,其他线程无法获得该锁,直到锁被释放。

可以说,锁是信号量的一种特殊形式,即二元信号量(Binary Semaphore),只有0和1两个状态。锁更加简单,只关注资源是否被占用,而信号量还关注资源的数量。

在实际应用中,锁更常用于实现互斥访问,而信号量更常用于实现线程同步。选择使用锁还是信号量取决于具体的并发需求和设计。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有