为了将进程以一种安全的方式进入休眠,我们需要牢记两条规则:
一、永远不要在原子上下文中进入休眠。
二、进程休眠后,对环境一无所知。唤醒后,必须再次检查以确保我们等待的条件真正为真
一、永远不要在原子上下文中进入休眠。
二、进程休眠后,对环境一无所知。唤醒后,必须再次检查以确保我们等待的条件真正为真
测试例子只是针对休眠的几个函数,例子本身没什么意义。测试例子在读的时候休眠直到条件满足后唤醒,再写的时候唤醒一个等待读的进程如果有进程在读的话。
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返回,当然这里不会打印什么数据。