對jiq中一段程序以及prepare_to_wait的理解
其中一個程序的代碼如下:
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()中的代碼。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.