linux 驱动学习之阻塞 I/O

为了将进程以一种安全的方式进入休眠,我们需要牢记两条规则:
一、永远不要在原子上下文中进入休眠。
二、进程休眠后,对环境一无所知。唤醒后,必须再次检查以确保我们等待的条件真正为真

测试例子只是针对休眠的几个函数,例子本身没什么意义。测试例子在读的时候休眠直到条件满足后唤醒,再写的时候唤醒一个等待读的进程如果有进程在读的话。


static DECLARE_WAIT_QUEUE_HEAD(hwait);
static unsigned state=0;
ssize_t fileops_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
{
   printk(KERN_ALERT "process %i (%s) wait for read\n",current->pid,current->comm);

//  wait_event(hwait,state!=0);                                /*进程将被置于非中断休眠*/   
    wait_event_interruptible(hwait,state!=0);                  /*进程可被信号中断休眠,返回非0值表示休眠被信号中断*/

/*等待限定时间jiffy,条件满足返回0,过程不可信号中断*/
//  wait_event_timeout(hwait,state!=0,10 * HZ);                //不可中断休眠等待10秒,超时返回0,成功返回剩余jiffies

/*等待限定时间jiffy,条件满足返回0,过程可被信号中断*/
//  wait_event_interruptible_timeout(hwait,state!=0,10*HZ);    //可中断休眠等待10秒,超时返回0,成功返回剩余jiffies,被中断返回-ERESTARTSYS

  state=0;
  printk(KERN_ALERT "process %i (%s) awke up\n",current->pid,current->comm);
  return 0;
}

ssize_t fileops_write(struct file *filp, const char __user *buff, size_t count, loff_t *offp)
{
  /*这里系统调用会一直写 直到写够count,如返回小于count的数,会再次调用此方法直到返回错误或写够count*/  
  printk(KERN_ALERT "process %i (%s) wake up all\n",current->pid,current->comm);
  state=1;

  wake_up_interruptible(&hwait);//注意不可中断的休眠不可用这个函数 应使用wake_up
  return count;
}


测试结果

打开多个终端并读设备
[root@localhost ctest]# cat /dev/moduledev60 
再打开一个设备往里面写数据

[root@localhost ctest]# echo 111 > /dev/moduledev60 

每写一次都会有个终端的cat返回,当然这里不会打印什么数据。






你可能感兴趣的:(linux 驱动学习之阻塞 I/O)