Concurrency in the Kernel

Concurrency in the Kernel

One way in which kernel programming differs greatly from conventional application programming is the issue of concurrency. Most applications, with the notable exception of multithreading applications, typically run sequentially, from the beginning to the end, without any need to worry about what else might be happening to change their environment. Kernel code does not run in such a simple world, and even the simplest kernel modules must be written with the idea that many things can be happening at once. 内核编程与传统应用程序编程有很大不同的一种方式是并发问题。 大多数应用程序,除了多线程应用程序,通常从头到尾按顺序运行,无需担心可能会发生什么改变其环境。 内核代码不会在这样一个简单的世界中运行,即使是最简单的内核模块也必须以可以同时发生许多事情的想法编写。

There are a few sources of concurrency in kernel programming. Naturally, Linux systems run multiple processes, more than one of which can be trying to use your driver at the same time. Most devices are capable of interrupting the processor; interrupt handlers run asynchronously and can be invoked at the same time that your driver is trying to do something else. Several software abstractions (such as kernel timers, introduced in Chapter 7) run asynchronously as well. Moreover, of course, Linux can run on symmetric multiprocessor (SMP) systems, with the result that your driver could be executing concurrently on more than one CPU. Finally, in 2.6, kernel code has been made preemptible; this change causes even uniprocessor systems to have many of the same concurrency issues as multiprocessor systems. 内核编程中有几个并发源。 自然地,Linux 系统运行多个进程,其中多个进程可以同时尝试使用您的驱动程序。 大多数设备都能够中断处理器; 中断处理程序异步运行,可以在您的驱动程序尝试执行其他操作的同时调用。 一些软件抽象(如第 7 章介绍的内核定时器)也异步运行。 此外,当然,Linux 可以在对称多处理器 (SMP) 系统上运行,因此您的驱动程序可以在多个 CPU 上同时执行。 最后,在 2.6 中,内核代码已被抢占; 这种变化甚至导致单处理器系统与多处理器系统有许多相同的并发问题。

As a result, Linux kernel code, including driver code, must be reentrant —it must be capable of running in more than one context at the same time. Data structures must be carefully designed to keep multiple threads of execution separate, and the code must take care to access shared data in ways that prevent corruption of the data. Writing code that handles concurrency and avoids race conditions (situations in which an unfortunate order of execution causes undesirable behavior) requires thought and can be tricky. Proper management of concurrency is required to write correct kernel code; for that reason, every sample driver in this book has been written with concurrency in mind. The techniques used are explained as we come to them; Chapter 5 has also been dedicated to this issue and the kernel primitives available for concurrency management. 因此,包括驱动程序代码在内的 Linux 内核代码必须是可重入的——它必须能够同时在多个上下文中运行。 数据结构必须经过精心设计,以保持多个执行线程分开,并且代码必须注意以防止数据损坏的方式访问共享数据。 编写处理并发并避免竞争条件(不幸的执行顺序导致不良行为的情况)的代码需要深思熟虑并且可能很棘手。 编写正确的内核代码需要适当的并发管理; 因此,本书中的每个示例驱动程序都在编写时考虑了并发性。 所使用的技术在我们谈到它们时进行了解释; 第 5 章也专门讨论了这个问题以及可用于并发管理的内核原语。

A common mistake made by driver programmers is to assume that concurrency is not a problem as long as a particular segment of code does not go to sleep (or "block"). Even in previous kernels (which were not preemptive), this assumption was not valid on multiprocessor systems. In 2.6, kernel code can (almost) never assume that it can hold the processor over a given stretch of code. If you do not write your code with concurrency in mind, it will be subject to catastrophic failures that can be exceedingly difficult to debug. 驱动程序程序员犯的一个常见错误是假设只要特定代码段不进入休眠(或“阻塞”),并发性就不是问题。 即使在以前的内核(不是抢占式的)中,这种假设在多处理器系统上也是无效的。 在 2.6 中,内核代码可以(几乎)永远不会假设它可以在给定的代码段上保持处理器。 如果您在编写代码时没有考虑到并发性,那么它将遭受灾难性的故障,并且调试起来非常困难。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mounter625

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值