程序排程之喚醒

2021-08-18 16:56:10 字數 2574 閱讀 8375

關於 __wait_event_interruptible中的for迴圈裡面的condition怎麼才能為真,自己很迷惑,因為如果condition為真,那麼在wait_event_interruptible就直接退出了。根本走不到for迴圈裡面。

#define wait_event_interruptible(wq, condition)				\

()#define __wait_event_interruptible(wq, condition, ret) \

do \

ret = -erestartsys; \

break; \

} \

finish_wait(&wq, &__wait); \

} while (0)

後來發現,關鍵是巨集定義,wait_event_interruptible和__wait_event_interruptible都是巨集定義,所以condition不是定義在裡面的區域性變數,而是呼叫wait_event_interruptible的外層的全域性變數。

a呼叫wait_event_interruptible時,condition一開始為false,所以進入for迴圈。然後b呼叫wait_event_interruptible時,condition為true則立即退出。但是修改了全域性condition,所以導致a能夠break

int try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)

cpu = select_task_rq(p, sd_balance_wake, wake_flags);

rq = cpu_rq(cpu);

update_rq_clock(rq);

activate_task(rq, p, 1);//重新進入排程佇列

check_preempt_curr(rq, p, wake_flags);

=>void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)

p->state = task_running;

}

關於schedule

schedule

=>cpu = smp_processor_id();//記錄當前的程序資訊

rq = cpu_rq(cpu);

prev = rq->curr;

=>if (prev->state && !(preempt_count() & preempt_active))//如果程序不就緒的話

==>if (unlikely((prev->state & task_interruptible) && unlikely(signal_pending(prev))))

===>prev->state = task_running;//訊號喚醒的話罰酒三杯,歸隊

==>else

deactivate_task(rq, prev, 1);//滾出就緒排程佇列,除非重新入隊,否則沒法排程到了,通過wake_up是可以的

=>prev->sched_class->put_prev_task(rq, prev);

=>next = pick_next_task(rq, prev);

=>sched_info_switch(prev, next);

=>if (likely(prev != next))//如果不是乙個程序

==>sched_info_switch(prev, next);//切換

=>else

==>如果是乙個程序就尷尬了,繼續執行唄

就緒佇列喚醒原理

inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)

default_wake_function

=>try_to_wake_up(curr->private, mode, sync);

complete原理

__wake_up_common(&x->wait, task_uninterruptible | task_interruptible, 1, 0, null);

=>curr->func(curr, mode, sync, key)

參考

wait_event_interruptible() 和 wake_up()的使用

linux模組程式設計(二)——執行不息的核心執行緒kthread

下面是linux核心的乙個乙個例項。

hub_events();從等待佇列裡面取出並刪除元素進行處理;

wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list) || kthread_should_stop());發現隊列為空進行休眠;

kick_khubd給等待佇列增加元素並喚醒佇列

usb列舉過程分析之守護程序及其喚醒

程序排程之建立程序

do fork struct pid pid alloc pid struct pid pid kmem cache alloc pid cachep,gfp kernel 分配pid結構體空間 nr alloc pidmap current nsproxy pid ns 分配pid程序號 pid ...

OS之程序排程

處理機排程 在多道程式程式的環境中,記憶體中存在著多個程序,程序往往大於處理機數目,這就要系統按照某種演算法,動態的將處理機分配給處於就緒狀態的程序。是之執行,分配處理機的任務就是由處理機排程完成的。排程實質上是一種資源分配。處理機排程演算法的目標 處理價排程演算法的共同目標 1 資源利用率,為了提...

程序排程之拉幫結派

uid linux os所有的使用者由乙個唯一的數字來標識,即使用者識別符號。user group id 為了和其它使用者由選擇地共享資料,每個使用者是乙個或者多個使用者組的一名成員,組由唯一的使用者組識別符號標識。每個檔案也恰好與乙個組相對應。例如,可以設定這樣的訪問許可權 擁有檔案的使用者具有對...