| 
		    
                    
   打开两个终端,分别运行上述两个应用程序,发现当在第二个终端中没有输入数据时,第一个终端没有输出(阻塞),每当我们在第二个终端中给globalvar输入一个值,第一个终端就会输出这个值,如下图: 
 
  关于上述例程,我们补充说一点,如果将驱动程序中的read函数改为: 
 
    
        
            static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off) {  //获取信号量:可能阻塞  if (down_interruptible(&sem))  {   return - ERESTARTSYS;  }
   //等待数据可获得:可能阻塞  if (wait_event_interruptible(outq, flag != 0))  {   return - ERESTARTSYS;  }  flag = 0;
   //临界资源访问  if (copy_to_user(buf, &global_var, sizeof(int)))  {   up(&sem);   return - EFAULT;  }
   //释放信号量  up(&sem);
   return sizeof(int); } | 
         
    
 
  即交换wait_event_interruptible(outq, flag != 0)和down_interruptible(&sem)的顺序,这个驱动程序将变得不可运行。实际上,当两个可能要阻塞的事件同时出现时,即两个wait_event或down摆在一起的时候,将变得非常危险,死锁的可能性很大,这个时候我们要特别留意它们的出现顺序。当然,我们应该尽可能地避免这种情况的发生! 
  还有一个与设备阻塞与非阻塞访问息息相关的论题,即select和poll,select和poll的本质一样,前者在BSD Unix中引入,后者在System V中引入。poll和select用于查询设备的状态,以便用户程序获知是否能对设备进行非阻塞的访问,它们都需要设备驱动程序中的poll函数支持。 
		    
                      
		      
		      
		   |