雪梨资讯

当前位置:主页 >> 资讯 >> 肾苞草属

开汽车锁小窍门管道理解xv643使用锁

发布时间:2024年07月15日    点击:[13]人次

Xv6 uses locks in many places to avoid race conditions. A simple example is in the IDE driver (4200) . As mentioned in the beginning of the chapter, iderw (4354) has a queue of disk requests and processors may add new requests to the list concurrently (4369) . To protect this list and other invariants in the driver, iderw acquires the ide-lock (4365) and releases it at the end of the function.

iderw

Xv 6在许多地方使用锁来避免竞争条件。一个简单的例子是IDE驱动程序(4200)。如本章开头所述,iderw(4354)有一个磁盘请求的队列和处理器可以并发地将新请求添加到列表(4369)。为了保护这个列表和驱动程序中的其他不变量,iderw获取了ide-lock(4365)并在函数结束时释放它。

Exercise 1 explores how to trigger the IDE driver race condition that we saw at the beginning of the chapter by moving the acquire to after the queue manipulation. It is worthwhile to try the exercise because it will make clear that it is not that easy to trigger the race, suggesting that it is difficult to find race-conditions bugs. It is not unlikely that xv6 has some races.

练习1探索如何通过将获取移动到队列操作之后来触发我们在本章开头看到的IDE驱动程序竞争条件。这个练习值得一试,因为它会清楚地表明,触发竞争并不那么容易,这表明很难找到竞争条件错误。xv6有一些竞争是有可能发生的。

A hard part about using locks is deciding how many locks to use and which data and invariants each lock protects. There are a few basic principles. First, any time a variable can be written by one CPU at the same time that another CPU can read or write it, a lock should be introduced to keep the two operations from overlapping. Second, remember that locks protect invariants: if an invariant involves multiple memory locations, typically all of them need to be protected by a single lock to ensure the invariant is maintained.

使用锁的一个困难部分是决定使用多少锁和每个锁保护哪些数据和不变量。有几个基本原则。首先,任何时候A变量可以由一个CPU写入,同时另一个CPU可以读取或写它时,应该引入一个锁来防止这两个操作重叠。其次,记住锁保护不变量:如果一个不变量涉及多个存储器位置,通常它们都需要由单个锁保护,以确保保持不变。

The rules above say when locks are necessary but say nothing about when locks are unnecessary, and it is important for efficiency not to lock too much, because locks reduce parallelism. If parallelism isn’t important, then one could arrange to have only a single thread and not worry about locks.

A simple kernel can do this on a multiprocessor by having a single lock that must be acquired on entering the kernel and released on exiting the kernel (though system calls such as pipe reads or wait would pose a problem). Many uniprocessor operating systems have been converted to run on multiprocessors using this approach, sometimes called a ‘‘giant kernel lock,’’ but the approach sacrifices parallelism: only one CPU can execute in the kernel at a time. If the kernel does any heavy computation, it would be more efficient to use a larger set of more fine-grained locks, so that the kernel could execute on multiple CPUs simultaneously.

上面的规则说明了何时需要锁,但没有说明何时不需要锁。且对于效率来说,不要锁定太多是很重要的,因为锁定减少并行性。如果并行性不重要,那么可以只安排一个线程,不用担心锁。

一个简单的内核可以在多处理器上做到这一点,方法是使用一个锁,该锁必须在进入内核时获取,并在退出内核时释放(尽管诸如管道读取或等待之类的系统调用会造成问题)。许多单处理器操作系统已被转换为运行在使用这种方法的多处理器,有时被称为“巨型内核锁”,但这种方法牺牲了并行性:一次只能在内核中执行一个CPU。如果内核进行任何繁重的计算,使用更大的更细粒度的锁,这样内核就可以同时在多个CPU上执行。

Ultimately, the choice of lock granularity is an exercise in parallel programming. Xv6 uses a few coarse data-structure specific locks (see Figure 4-2). For example, xv6 has a lock that protects the whole process table and its invariants, which are described in Chapter 5. A more fine-grained approach would be to have a lock per entry in the process table so that threads working on different entries in the process table can proceed in parallel. However, it complicates operations that have invariants over the whole process table, since they might have to acquire several locks. Subsequent chapters will discuss how each part of xv6 deals with concurrency, illustrating how to use locks.

最终,锁粒度的选择是并行编程中的一个练习。Xv6使用了一些粗略的数据结构特定的锁(见图4-2)。例如,xv6有一个保护整个进程表及其不变量的锁,这将在第5章中描述。一种更细粒度的方法是在进程表中为每个条目设置一个锁,这样处理进程表中不同条目的线程就可以并行进行。但是,它使在整个进程表上具有不变量的操作变得复杂,因为它们可能必须获取多个锁。随后的章节将讨论xv6的各个部分如何处理并发,并说明如何使用锁。

纪念斯隆凯特林看病流程

文存阅刊邮箱

体育视野编辑部

数字化用户官网