解析Linux核心的同步與互斥機制(二)

來源:互聯網
上載者:User

源出處:http://www.startos.com/linux/tips/2011011921499_2.html

全域或者在棧中定義一個wait_queue_t類型變數的同時對其初始化,這保證了系統的可靠性,避免因使用者忘記初始化時導致的問題。通用的初始化宏,tsk為任意指標。分兩步:

  1) 內部宏__WAITQUEUE_INITIALIZER初始化相應成員;當wq內嵌在別的結構體中時,此宏很重要,提高了可移植性;

  2) 提供給外部的介面,定義一個變數,並將第一步的結果賦值給該變數。

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

  {

  q->flags = 0;

  q->private = p;

  q->func = default_wake_function;

  }

  動態初始化一個等待隊列入口項,將其和當前進程關聯起來,以便喚醒當前進程。

  2.1.3 資料結構設計規則

  今後凡遇到新設計一類結構體,若此類結構體變數必須初始化且有相對集中的操作,則應提供以下兩個操作介面:

  a) 定義建立一個結構體變數,並初始化之;

  b) 動態初始化一個已經分配記憶體的該類變數

  為了適應在堆棧及全域等任意地方分配的該變數,其應該接收指向該類變數的指標。

  2.2 陳舊sleep_on系列

  //初始化一個wait_queue_t

  #define SLEEP_ON_VAR \

  unsigned long flags; \

  wait_queue_t wait; \

  init_waitqueue_entry(&wait, current);

  //添加到隊列中

  #define SLEEP_ON_HEAD \

  spin_lock_irqsave(&q->lock,flags); \

  __add_wait_queue(q, &wait); \

  spin_unlock(&q->lock);

  //從隊列中刪除

  #define SLEEP_ON_TAIL \

  spin_lock_irq(&q->lock); \

  __remove_wait_queue(q, &wait); \

  spin_unlock_irqrestore(&q->lock, flags);

  SLEEP_ON_VAR、 SLEEP_ON_HEAD及SLEEP_ON_ TAIL總是同時出現,不可分割。上述宏不是函數,只是連續的運算式而已,因為函數就將他們隔離開來了,函數他退出後變數就無意義了。也不能寫成 do――while的多語句宏,變數定義離開“{}”後就沒有意義了。是為了編寫代碼更清晰明了,同時避免多寫字,實際上就是代碼封裝複用。

  void fastcall __sched interruptible_sleep_on(wait_queue_head_t *q)

  {

  SLEEP_ON_VAR //注意沒“;”

  current->state = TASK_INTERRUPTIBLE;

  SLEEP_ON_HEAD

  schedule(); //此處可能出問題

  SLEEP_ON_TAIL

  }

  EXPORT_SYMBOL(interruptible_sleep_on);

  添加到隊列和從隊列中刪除由同一個模組做,符合模組設計規則,減小了耦合性。

  喚醒的wakeup只負責改變進程狀態,進程重新獲得cpu後從隊列中刪除。

  long fastcall __sched

  interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout)

  {

  SLEEP_ON_VAR

  current->state = TASK_INTERRUPTIBLE;

  SLEEP_ON_HEAD

  timeout = schedule_timeout(timeout);

  SLEEP_ON_TAIL

  return timeout;

  }

  EXPORT_SYMBOL(interruptible_sleep_on_timeout);

  void fastcall __sched sleep_on(wait_queue_head_t *q)

  {

  SLEEP_ON_VAR

  current->state = TASK_UNINTERRUPTIBLE;

  SLEEP_ON_HEAD

  schedule();

  SLEEP_ON_TAIL

  }

  EXPORT_SYMBOL(sleep_on);

  long fastcall __sched sleep_on_timeout(wait_queue_head_t *q, long timeout)

  {

  SLEEP_ON_VAR

  current->state = TASK_UNINTERRUPTIBLE;

  SLEEP_ON_HEAD

  timeout = schedule_timeout(timeout);

  SLEEP_ON_TAIL

  return timeout;

  }

  EXPORT_SYMBOL(sleep_on_timeout);

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.