其中一个程序的代码如下:
static int jiq_read_wq(char *buf, char **start, off_t offset,
int len, int *eof, void *data)
{
DEFINE_WAIT(wait);
jiq_data.len = 0; /* nothing printed, yet */
jiq_data.buf = buf; /* print in this place */
jiq_data.jiffies = jiffies; /* initial time */
jiq_data.delay = 0;
prepare_to_wait(&jiq_wait, &wait, TASK_INTERRUPTIBLE);
printk(KERN_ALERT "work qian is %4li/n",jiffies);
schedule_work(&jiq_work);
printk(KERN_ALERT "work hou is %4li/n",jiffies);
schedule();
printk(KERN_ALERT "schedule hou is %4li/n",jiffies);
finish_wait(&jiq_wait, &wait);
*eof = 1;
return jiq_data.len;
}
其中还有一个用于唤醒if (len > LIMIT) {
printk(KERN_ALERT "jiffies of len wake_up is %4li/n",jiffies);
wake_up_interruptible(&jiq_wait);
return 0;
}
还有一个初始化INIT_WORK(&jiq_work, jiq_print_wq, &jiq_data);
我的理解如下:
1 首先在初始化时由INIT_WORK(&jiq_work, jiq_print_wq, &jiq_data)初始化一个工作队列。这个队列并提交给内核由一个单独的线程去管理。
2 程序按照这个步骤执行
prepare_to_wait(&jiq_wait, &wait, TASK_INTERRUPTIBLE);
printk(KERN_ALERT "work qian is %4li/n",jiffies);
schedule_work(&jiq_work);
printk(KERN_ALERT "work hou is %4li/n",jiffies);
其中要说明的是prepare_to_wait的作用是把该进程标记为TASK_INTERRUPTIBLE,并添加到等待队列中。(通过实验知道,程序并不会在这里停下来,不知道理解的对不对)
schedule_work(&jiq_work);使工作队列起作用。
3 程序继续执行
schedule();
printk(KERN_ALERT "schedule hou is %4li/n",jiffies);
finish_wait(&jiq_wait, &wait);
程序通过schedule();调度另一个程序运行。另一个程序通过唤醒当前的这个程序,然后到finish_wait结束。
通过实验知道程序会在schedule();处停住。不知道对不对。只有继续看书,以后在理解了。
挂起的进程并不会自动转入运行的,因此,还需要一个唤醒动作,这个动作由wake_up_interruptible()完成,它将遍历作为参数传入的 log_wait等待队列,将其中所有的元素(通常都是task_struct)置为运行态,从而可被调度到,执行 __wait_event_interruptible()中的代码。
static int jiq_read_wq(char *buf, char **start, off_t offset,
int len, int *eof, void *data)
{
DEFINE_WAIT(wait);
jiq_data.len = 0; /* nothing printed, yet */
jiq_data.buf = buf; /* print in this place */
jiq_data.jiffies = jiffies; /* initial time */
jiq_data.delay = 0;
prepare_to_wait(&jiq_wait, &wait, TASK_INTERRUPTIBLE);
printk(KERN_ALERT "work qian is %4li/n",jiffies);
schedule_work(&jiq_work);
printk(KERN_ALERT "work hou is %4li/n",jiffies);
schedule();
printk(KERN_ALERT "schedule hou is %4li/n",jiffies);
finish_wait(&jiq_wait, &wait);
*eof = 1;
return jiq_data.len;
}
其中还有一个用于唤醒if (len > LIMIT) {
printk(KERN_ALERT "jiffies of len wake_up is %4li/n",jiffies);
wake_up_interruptible(&jiq_wait);
return 0;
}
还有一个初始化INIT_WORK(&jiq_work, jiq_print_wq, &jiq_data);
我的理解如下:
1 首先在初始化时由INIT_WORK(&jiq_work, jiq_print_wq, &jiq_data)初始化一个工作队列。这个队列并提交给内核由一个单独的线程去管理。
2 程序按照这个步骤执行
prepare_to_wait(&jiq_wait, &wait, TASK_INTERRUPTIBLE);
printk(KERN_ALERT "work qian is %4li/n",jiffies);
schedule_work(&jiq_work);
printk(KERN_ALERT "work hou is %4li/n",jiffies);
其中要说明的是prepare_to_wait的作用是把该进程标记为TASK_INTERRUPTIBLE,并添加到等待队列中。(通过实验知道,程序并不会在这里停下来,不知道理解的对不对)
schedule_work(&jiq_work);使工作队列起作用。
3 程序继续执行
schedule();
printk(KERN_ALERT "schedule hou is %4li/n",jiffies);
finish_wait(&jiq_wait, &wait);
程序通过schedule();调度另一个程序运行。另一个程序通过唤醒当前的这个程序,然后到finish_wait结束。
通过实验知道程序会在schedule();处停住。不知道对不对。只有继续看书,以后在理解了。
挂起的进程并不会自动转入运行的,因此,还需要一个唤醒动作,这个动作由wake_up_interruptible()完成,它将遍历作为参数传入的 log_wait等待队列,将其中所有的元素(通常都是task_struct)置为运行态,从而可被调度到,执行 __wait_event_interruptible()中的代码。