⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linux设备驱动程序学习(3)-并发和竞态 - linux设备驱动程序 - tekkaman ninja.htm

📁 Linux设备驱动程序学习(3)-并发和竞态 - Linux设备驱动程序.rar
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                              style="FONT-WEIGHT: normal; COLOR: rgb(0,1,2)">第五章并发和竞态的学习。</SPAN></FONT> 
                              </P>
                              <P align=left><FONT color=#000000><SPAN 
                              style="FONT-WEIGHT: normal; COLOR: rgb(0,1,2)">对并发的管理是操作系统编程中核心的问题之一。</SPAN></FONT><FONT 
                              color=#000000><SPAN 
                              style="FONT-WEIGHT: normal; COLOR: rgb(0,1,2)">&nbsp;并发产生竞态,竞态导致<FONT 
                              color=#0000ff>共享数据</FONT>的非法访问。因为竞态是一种极端低可能性的事件,因此程序员往往会忽视竞态。但是<FONT 
                              color=#0000ff>在计算机世界中,百万分之一的事件可能没几秒就会发生</FONT>,而其结果是灾难性的。</SPAN></FONT></P><FONT 
                              color=#000000><FONT size=2>
                              <HR id=null>
                              </FONT></FONT><FONT color=#0000ff 
                              size=4><STRONG>一、并发及其管理</STRONG></FONT> 
                              <DIV>竞态通常是作为<FONT 
                              color=#ff0000>对资源的共享访问</FONT>结果而产生的。</DIV>
                              <DIV>在设计自己的驱动程序时,第一个要记住的规则是:<FONT 
                              color=#ff0000>只要可能,就应该避免资源的共享。</FONT>若没有并发访问,就不会有竞态。<FONT 
                              color=#0000ff>这种思想的最明显的应用是避免使用全局变量。</FONT></DIV>
                              <DIV>但是,资源的共享是不可避免的 ,如硬件资源本质上就是共享、指针传递等等。</DIV>
                              <DIV>资源共享的硬性规则:</DIV>
                              <DIV>(1)在单个执行线程之外共享硬件或软件资源的任何时候,因为另外一个线程可能产生对该资源的不一致观察,因此<FONT 
                              color=#ff0000>必须显示地管理对该资源的访问</FONT>。--访问管理的常见技术成为“锁定”或者“互斥”:确保一次只有一个执行线程可操作共享资源。</DIV>
                              <DIV>(2)当内核代码创建了一个可能和其他内核部分共享的对象时,该对象必须在还有其他组件引用自己时保持存在(并正确工作)。对象尚不能正确工作时,不能将其对内核可用。</DIV>
                              <DIV>
                              <HR id=null>
                              </DIV>
                              <DIV><FONT color=#0000ff 
                              size=4><STRONG>二、信号量和互斥体</STRONG></FONT></DIV>
                              <DIV>一个信号量(semaphore: 
                              旗语,信号灯)本质上是一个整数值,它和一对函数联合使用,这一对函数通常称为P和V。希望进入临届区的进程将在相关信号量上调用P;如果信号量的值大于零,则该值会减小一,而进程可以继续。相反,如果信号量的值为零(或更小),进程必须等待知道其他人释放该信号。对信号量的解锁通过调用V完成;该函数增加信号量的值,并在必要时唤醒等待的进程。</DIV>
                              <DIV>当信号量用于互斥时(即避免多个进程同是在一个临界区运行),信号量的值应初始化为1。这种信号量在任何给定时刻只能由单个进程或线程拥有。在这种使用模式下,一个信号量有事也称为一个“互斥体(mutex)”,它是互斥(mutual 
                              exclusion)的简称。<FONT 
                              color=#0000ff>Linux内核中几乎所有的信号量均用于互斥</FONT>。</DIV>
                              <DIV>使用信号量,内核代码必须包含<FONT 
                              color=#0000ff>&lt;asm/semaphore.h&gt;</FONT> 
                              。</DIV>
                              <DIV>&nbsp;</DIV>
                              <DIV>以下是信号量初始化的方法:</DIV>
                              <DIV>
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: rgb(0,0,0)"><FONT face=新宋体><SPAN 
                                style="COLOR: rgb(255,153,0)">/*初始化函数*/</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                sema_init<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                semaphore <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>sem<SPAN 
                                style="COLOR: rgb(0,0,204)">,</SPAN> <SPAN 
                                style="COLOR: rgb(0,0,255)">int</SPAN> val<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></DIV>
                              <DIV>&nbsp;</DIV>
                              <DIV>由于信号量通常被用于互斥模式。所以以下是内核提供的一组辅助函数和宏: 
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: rgb(0,0,0)"><FONT face=新宋体><SPAN 
                                style="COLOR: rgb(255,153,0)">/*方法一、声明+初始化宏*/</SPAN><BR>DECLARE_MUTEX<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>name<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR>DECLARE_MUTEX_LOCKED<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>name<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR><BR><SPAN 
                                style="COLOR: rgb(255,153,0)">/*方法二、初始化函数*/</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                init_MUTEX<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                semaphore <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>sem<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                init_MUTEX_LOCKED<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                semaphore <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>sem<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR><BR><SPAN 
                                style="COLOR: rgb(255,153,0)">/*带有“_LOCKED”的是将信号量初始化为0,即锁定,允许任何线程访问时必须先解锁。没带的为1。*/</SPAN></FONT><BR></SPAN></CODE></P></TD></TR></TBODY></TABLE></DIV>
                              <DIV>&nbsp;</DIV>
                              <DIV>P函数为: 
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: rgb(0,0,0)"><FONT face=新宋体><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                down<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                semaphore <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>sem<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">; <FONT 
                                color=#ff9900>/*不推荐使用,会建立不可杀进程*/</FONT></SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">int</SPAN> 
                                down_interruptible<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                semaphore <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>sem<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;<FONT 
                                color=#ff9900>/*推荐使用,使用<FONT 
                                color=#ff9900>down_interruptible需要格外小心,若操作被中断,该函数会返回非零值,而调用这不会拥有该信号量。对down_interruptible的正确使用需要始终检查返回值,并做出相应的响应。</FONT>*/</FONT></SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">int</SPAN> 
                                down_trylock<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                semaphore <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>sem<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;<FONT 
                                color=#ff9900>/*带有<FONT 
                                color=#ff9900>“_trylock”的</FONT>永不休眠,若信号量在调用是不可获得,会返回非零值。*/</FONT></SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></DIV>
                              <DIV>&nbsp;</DIV>
                              <DIV>V函数为: 
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: rgb(0,0,0)"><FONT face=新宋体><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> up<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                semaphore <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>sem<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;<FONT 
                                color=#ff9900>/*任何拿到信号量的线程都必须通过一次(只有一次)对up的调用而释放该信号量。在出错时,要特别小心;若在拥有一个信号量时发生错误,必须在将错误状态返回前释放信号量。*/</FONT><BR></SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></DIV>
                              <DIV>&nbsp;</DIV>
                              <DIV><FONT color=#0000ff 
                              size=3><STRONG>在scull中使用信号量</STRONG></FONT></DIV>
                              <DIV>&nbsp;</DIV>
                              <DIV>其实在之前的实验中已经用到了信号量的代码,在这里提一下应该注意的地方:</DIV>
                              <DIV>在初始化scull_dev的地方: 
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: rgb(0,0,0)"><FONT face=新宋体><SPAN 
                                style="COLOR: rgb(255,153,0)">/* Initialize each 
                                device. 
                                */</SPAN><BR>&nbsp;&nbsp;&nbsp;&nbsp;<SPAN 
                                style="COLOR: rgb(0,0,255)">for</SPAN> <SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>i <SPAN 
                                style="COLOR: rgb(0,0,204)">=</SPAN> 0<SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN> i <SPAN 
                                style="COLOR: rgb(0,0,204)">&lt;</SPAN> 
                                scull_nr_devs<SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN> i<SPAN 
                                style="COLOR: rgb(0,0,204)">+</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">+</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN> <SPAN 
                                style="COLOR: rgb(0,0,204)">{</SPAN><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scull_devices<SPAN 
                                style="COLOR: rgb(0,0,204)">[</SPAN>i<SPAN 
                                style="COLOR: rgb(0,0,204)">]</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">.</SPAN>quantum 
                                <SPAN style="COLOR: rgb(0,0,204)">=</SPAN> 
                                scull_quantum<SPAN 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -