很多程式設計的書裡在介紹mutex和semaphore的時候都會說,mutex是一種特殊的semaphore.
當semaphore的n=1時,就變成了binary semaphore,也就等同與mutex了。
但是實際上,在linux中,他們的實現什有區別的,導致最後應用的行為也是有區別的。
先看下面這個例子,這是一段linux kernel的**:
#include #include #include #include #include #include static define_mutex(g_mutex);
static define_semaphore(g_semaphore);
static int fun1(void *p)
return 0;
}static int fun2(void *p)
return 0;
}static int fun3(void *p)
return 0;
}static int fun4(void *p)
return 0;
}static int hello_init(void)
module_init(hello_init);
這段**很簡單,4個執行緒,2個去獲取mutex,2個去獲取semaphore。
我們可以先只enable thread1和thread2。
我開始預期的結果什輸出1212121212...
但是實際的結果是111111111...22222222222...11111111111...
假設enable thread3和thread4,輸出則變成了34343434343434...
顯然,mutex和semaphore使用的結果不一樣。
為什麼會造成這樣的結果哪?
我們分析一下kernel裡mutex和semaphore的實現就可以明白了
kernel/mutex.c
__mutex_unlock_common_slowpath(atomic_t *lock_count, int nested)
spin_unlock_mutex(&lock->wait_lock, flags);
}
在解鎖的時候,會先把lock->count設定成1,
然後從等待這個mutex的佇列裡取出第乙個任務,並wake_up這個任務。
這裡要注意,wake_up_process只是把這個任務設定成可排程,並不是直接就進行排程了。
所以當乙個執行緒unlock mutex之後,只要在自己還沒有被排程出去之前再次很快的lock mutex的話,他依舊會成功。
於是,這就出現了一開始那個程式的結果。
在**本身沒有死鎖的情況下,不合適得使用mutex,會造成飢餓的發生。
那semaphore到底是如何避免這樣的情況發生的哪?
kernel/semaphore.c
void down(struct semaphore *sem)
static inline int __sched __down_common(struct semaphore *sem, long state,
long timeout)
timed_out:
list_del(&waiter.list);
return -etime;
interrupted:
list_del(&waiter.list);
return -eintr;
}void up(struct semaphore *sem)
static noinline void __sched __up(struct semaphore *sem)
首先在down的時候,回去檢視sem->count的值,假如大於0,就進行--操作。
這就好比第乙個執行緒去down semaphore。
等到第二個執行緒再去down的時候,count為0了,就進入了__down_common函式。
這個函式裡面會一直檢查waiter.up,知道為true了才會退出。
至此,第二個執行緒就被block在了down函式裡。
等到第乙個執行緒up semaphore,假如這個semaphore的等待佇列裡還有任務,則設定waiter->up為true並喚醒任務。
這裡用的也是wake_up_process,貌似和mutex的實現什一樣的,但是接下來就不一樣了。
假設第乙個執行緒之後又很快的去down semaphore,會發生什麼哪?
由於sem->count還是為0,這個執行緒在down的時候就會被block住而發生排程。
第二個執行緒此時就可以獲得semaphore而繼續執行**了。
一直直到沒有任何執行緒在等待佇列裡了,sem->count才會被++。
所以,semaphore就變成了這樣的行為。
總結:mutex在使用時沒有任何順序的保證,它僅僅是保護了資源,但是效率會比較高。
而semaphore則有順序的保證,使得每個使用者都能依次獲得他,但是相應的會損失一點效率。
linux中mutex和semaphore的區別
很多程式設計的書裡在介紹mutex和semaphore的時候都會說,mutex是一種特殊的semaphore.當semaphore的n 1時,就變成了binary semaphore,也就等同與mutex了。但是實際上,在linux中,他們的實現什有區別的,導致最後應用的行為也是有區別的。先看下面這...
SEM和SEM如何互相幫助?
sem和seo是 搜尋營銷的標配,如果把這兩種方式打個比方的話,sem相當於醫生給開的處方藥 止痛藥 seo相當於醫生給開的處方藥 抗生素 抗生素 seo 是醫生專門用來給患者從根本上解決病痛的處方藥,缺點在於,你不知道什麼時候會治好,以及以後會不會又犯病 seo在執行的時候,很難立馬見效,時間很長...
sd和sem啥區別 SD與SEM區別
sd 標準差 standard deviation 中文環境中又常稱均方差,但不同於均方誤差 mean squared error,均方誤差是各資料偏離真實值的距離平方的平均數,也即誤差平方和的平均數,計算公式形式上接近方差,它的開方叫均方根誤差,均方根誤差才和標準差形式上接近 標準差是離均差平方和...