亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標題: 用戶態(tài)自旋鎖和內(nèi)核態(tài)自旋鎖的區(qū)別? [打印本頁]

作者: DVD0423    時間: 2015-01-30 16:18
標題: 用戶態(tài)自旋鎖和內(nèi)核態(tài)自旋鎖的區(qū)別?
如題,小弟內(nèi)核菜鳥,最近研究自旋鎖,發(fā)現(xiàn)用戶態(tài)也有自旋鎖實現(xiàn)(如pthread),不知道用戶態(tài)下的自旋鎖和內(nèi)核態(tài)的區(qū)別是什么?
或者說用戶態(tài)下的自旋鎖實現(xiàn)原理是什么?還望大神賜教。
作者: amarant    時間: 2015-01-30 17:07
不負責任的回答,用戶的鎖最后也用的內(nèi)核里面的。
作者: Tinnal    時間: 2015-01-31 08:22
回復(fù) 1# DVD0423

我有點不同意amarant的解析,有點以偏概全。

其實這個問題的核心就是什么才叫spinlock?只要符合拿不到鎖時自旋等待而是不去睡眠這個條件,就符合自旋鎖的定義,它的實現(xiàn)就是一個自旋鎖的!不管在那實現(xiàn),不管最終的實現(xiàn)會有什么其它的效果。
跟拿到鎖以后是否還會被調(diào)度走沒有關(guān)系,其實內(nèi)核的spinlock實現(xiàn)在打開內(nèi)核搶占時,拿不到鎖,也會被調(diào)度出去。

http://www.unix.com/man-page/freebsd/3/pthread_spin_lock/
The pthread_spin_lock() function will acquire lock if it is not currently owned by another
     thread.  If the lock cannot be acquired immediately, it will spin attempting to acquire the
     lock (it will not sleep) until it becomes available.



   
作者: 鎮(zhèn)水鐵牛    時間: 2015-01-31 08:37
回復(fù) 3# Tinnal

有個疑問請教下:
內(nèi)核的spinlock實現(xiàn)在打開內(nèi)核搶占時,拿不到鎖,也會被調(diào)度出去。
疑問:內(nèi)核開搶占時,拿不到鎖就被調(diào)度,就違背自旋的本意了吧?
   
作者: Tinnal    時間: 2015-01-31 08:41
本帖最后由 Tinnal 于 2015-01-31 08:42 編輯

回復(fù) 4# 鎮(zhèn)水鐵牛


    沒有違背呀。1. 從代碼來說,它還在自我的循環(huán)里;2.它的狀態(tài)還是running的狀態(tài),沒有去睡眠等待。
作者: yang511yang    時間: 2015-01-31 10:25
回復(fù) 3# Tinnal

下面是linux-2.6.10的代碼:
  1. #define spin_lock(lock)                _spin_lock(lock)

  2. void __lockfunc _spin_lock(spinlock_t *lock)
  3. {
  4.         [color=Red]preempt_disable();
  5. [/color]        if (unlikely(!_raw_spin_trylock(lock)))
  6.                 __preempt_spin_lock(lock);
  7. }

  8. static inline void __preempt_spin_lock(spinlock_t *lock)
  9. {
  10.         if (preempt_count() > 1) {
  11.                 _raw_spin_lock(lock);
  12.                 return;
  13.         }

  14.         do {
  15.                 [color=Red]preempt_enable();
  16. [/color]                while (spin_is_locked(lock))
  17.                         cpu_relax();
  18.                 [color=Red]preempt_disable();
  19. [/color]        } while (!_raw_spin_trylock(lock));
  20. }
復(fù)制代碼
=============================================================
下面是linux-3.10.0的代碼:
  1. static inline void spin_lock(spinlock_t *lock)
  2. {
  3.         raw_spin_lock(&lock->rlock);
  4. }

  5. #define raw_spin_lock(lock)        _raw_spin_lock(lock)


  6. void __lockfunc _raw_spin_lock(raw_spinlock_t *lock)
  7. {
  8.         __raw_spin_lock(lock);
  9. }


  10. static inline void __raw_spin_lock(raw_spinlock_t *lock)
  11. {
  12.         [color=Red]preempt_disable();   
  13. [/color]        spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
  14.         LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
  15. }


  16. static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock)
  17. {
  18.         __acquire(lock);
  19.         arch_spin_lock(&lock->raw_lock);
  20. }

  21. static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
  22. {
  23.         register struct __raw_tickets inc = { .tail = TICKET_LOCK_INC };

  24.         inc = xadd(&lock->tickets, inc);
  25.         if (likely(inc.head == inc.tail))
  26.                 goto out;

  27.         inc.tail &= ~TICKET_SLOWPATH_FLAG;
  28.         for (;;) {
  29.                 unsigned count = SPIN_THRESHOLD;

  30.                 do {
  31.                         if (ACCESS_ONCE(lock->tickets.head) == inc.tail)
  32.                                 goto out;
  33.                         cpu_relax();
  34.                 } while (--count);
  35.                 __ticket_lock_spinning(lock, inc.tail);
  36.         }
  37. out:        barrier();        /* make sure nothing creeps before the lock is taken */
  38. }
復(fù)制代碼
新版本取消了自旋等待過程中的搶占使能。
   
作者: DVD0423    時間: 2015-02-02 09:00
我知道你的意思,可能我沒表述清楚,我想說的是他們的底層是不是一樣的,比如X86架構(gòu),他們的實現(xiàn)是不是用的相同的指令。因為我最近做的實驗是檢測自旋鎖時間,這樣就出現(xiàn)一個問題,到底是只檢測內(nèi)核中的還是也要檢測用戶層下的?回復(fù) 3# Tinnal


   
作者: Tinnal    時間: 2015-02-02 13:53
回復(fù) 7# DVD0423


    代碼肯定是不一樣的呀,而且用戶態(tài)和內(nèi)核態(tài)沒有可比性。
作者: DVD0423    時間: 2015-02-02 18:48
回復(fù) 8# Tinnal 我的關(guān)鍵問題就是想知道這兩個不一樣的地方。比如一個帶有自旋鎖的程序到底在指令層是不是調(diào)用了內(nèi)核的自旋鎖?這涉及到我的自旋鎖檢測的實驗是不是只需要檢測內(nèi)核層,請問您了解嗎?求指導(dǎo)。


   
作者: Tinnal    時間: 2015-02-03 00:46
pthread_spin_lock應(yīng)該是沒有調(diào)用內(nèi)核的Spinlock實現(xiàn)的。內(nèi)核的spinlock不是一個系統(tǒng)調(diào)用。
作者: 爻易    時間: 2015-02-04 14:58
鎖的原理就是 讀-測試-寫 的原子操作,機器指令提供了此類功能,與是否內(nèi)核態(tài)無關(guān)!

自旋鎖加鎖失敗會不停地試圖加鎖,因此必須能被搶占調(diào)度,否則就會死鎖。
作者: DVD0423    時間: 2015-02-05 15:15
回復(fù) 11# 爻易 請問你知道一個用戶態(tài)進程在執(zhí)行到自旋鎖的時候,x86機器是如何運行的嘛?謝謝大神指教。


   
作者: DVD0423    時間: 2015-02-05 15:21
回復(fù) 10# Tinnal 這個我知道,關(guān)鍵是我現(xiàn)在只知道內(nèi)核態(tài)的自旋鎖的作用,它是作用于整個系統(tǒng)的cpu同步。而pthread,這個是多線程編程的東西,對于另外一個進程是透明的,所以它的自旋鎖執(zhí)行流程不是很清楚,或者說它的具體作用不知道是什么?


   
作者: Tinnal    時間: 2015-02-05 19:37
回復(fù) 13# DVD0423


唉,想這么復(fù)雜干嗎,就是一種互斥的機制。典型的特征是拿不到鎖時自旋而不睡眠。

至于是多線程能用還是多進程能用,不是什么關(guān)鍵點,方案都能實現(xiàn)。
作者: yang511yang    時間: 2015-02-05 21:15
本帖最后由 yang511yang 于 2015-02-05 21:16 編輯

回復(fù) 11# 爻易
"自旋鎖加鎖失敗會不停地試圖加鎖,因此必須能被搶占調(diào)度,否則就會死鎖"
為什么會死鎖,linux-3.10.0內(nèi)核好像就不再使能搶占了啊!

   
作者: DVD0423    時間: 2015-02-06 10:24
回復(fù) 14# Tinnal 我是搞這個研究的,必須要很清楚細節(jié)才行,深究起來只會越做越糊涂


   
作者: DVD0423    時間: 2015-02-06 10:26
回復(fù) 15# yang511yang 以前會現(xiàn)在不會了


   
作者: Tinnal    時間: 2015-02-06 20:56
回復(fù) 16# DVD0423


要研究,就行好好看去google, 應(yīng)用態(tài)的外加好好看MAN手冊。

“它是作用于整個系統(tǒng)的cpu同步” 這種說法是你搜出來的?還是你自己理解的。作為研究,這句話一點都不嚴謹!


好好先去google吧。學術(shù)不是問出來的。

http://en.wikipedia.org/wiki/Spinlock
http://pubs.opengroup.org/online ... read_spin_lock.html
http://www.searchtb.com/2011/01/ ... hread-spinlock.html
http://www.ibm.com/developerworks/cn/linux/l-cn-spinlock/
作者: DVD0423    時間: 2015-02-07 17:31
本帖最后由 DVD0423 于 2015-02-07 17:44 編輯

回復(fù) 18# Tinnal
抱歉,這句話確實不嚴謹,主要是我是研究同步問題的所以就直接說了出來,應(yīng)該是作用于整個系統(tǒng)的cpu,同步只是其中一部分。這是我的錯。
但是幫別人就幫別人,還是不要帶一絲的高高在上的心態(tài)吧,如果你不覺得,那至少我感覺到了。你給我的鏈接我全看過,我發(fā)帖只是希望進度更快,而且我發(fā)帖是希望有牛人能真正幫到我。
我不是來問你什么是自旋鎖這種浮于表面的概念性的問題的。

一事歸一事,最后還是很感謝你花時間幫了我,真心感謝。



   
作者: scotthuang1989    時間: 2015-02-09 22:59
回復(fù) 19# DVD0423


是否理解為當Cpu在自旋的時候,至少本地CPU的內(nèi)核搶占是被禁止的。不知道這個理解是否正確。


   
作者: DVD0423    時間: 2015-02-10 10:51
回復(fù) 4# 鎮(zhèn)水鐵牛

現(xiàn)在的內(nèi)核自旋鎖用的是ticket spinlock, 就是排隊自旋鎖,這樣就實現(xiàn)了公平性,減少了鎖釋放時產(chǎn)生的cpu爭用鎖開銷,同時在linux里如果一個自旋鎖一直自旋不釋放,達到一定閾值后就會進入睡眠狀態(tài),有人說睡眠了還在running,這點我表示懷疑。

我覺得只有暴露自己的錯誤才能進步,如果我說的不對請勿鄙視
   
作者: DVD0423    時間: 2015-02-10 11:20
回復(fù) 2# amarant
用戶態(tài)(ring3)如果想使用內(nèi)核(ring0)的東西,要進行系統(tǒng)調(diào)用,進行系統(tǒng)調(diào)用(中斷)的開銷很大,要進行用戶態(tài)上下文的保存。所以我感覺用戶態(tài)的自旋鎖應(yīng)該不會是系統(tǒng)調(diào)用吧(我主要研究內(nèi)核態(tài),所以不確定)。

還有大家看看我的理解是不是錯的,我也想知道:在x86硬件上,操作系統(tǒng)運行在ring0,可以執(zhí)行任何指令,而用戶態(tài)運行在ring3上,只能執(zhí)行自己進程相關(guān)指令,這樣就保證了系統(tǒng)安全。同時用戶態(tài)不必經(jīng)過內(nèi)核態(tài),內(nèi)核只是一種管理工具,只有在用戶需要擴權(quán),需要運行一些ring0的指令的時候才經(jīng)過內(nèi)核態(tài),而這個途徑就是系統(tǒng)調(diào)用。(個人見解,如果有人告訴我錯了,那我才能認識的更深入)

對了,用戶態(tài)調(diào)用內(nèi)核態(tài)的東西是不是只有系統(tǒng)調(diào)用這個唯一途徑?
作者: firocu    時間: 2016-05-31 11:26
本帖最后由 firocu 于 2016-05-31 11:27 編輯

我來貼段gcc里面的實現(xiàn), 可以看出來是沒有差別的(FIXME):
  1. int
  2. pthread_spin_lock (pthread_spinlock_t *lock)
  3. {
  4.   /* atomic_exchange usually takes less instructions than
  5.      atomic_compare_and_exchange.  On the other hand,
  6.      atomic_compare_and_exchange potentially generates less bus traffic
  7.      when the lock is locked.
  8.      We assume that the first try mostly will be successful, and we use
  9.      atomic_exchange.  For the subsequent tries we use
  10.      atomic_compare_and_exchange.  */
  11.   if (atomic_exchange_acq (lock, 1) == 0)
  12.     return 0;

  13.   do  
  14.     {   
  15.       /* The lock is contended and we need to wait.  Going straight back
  16.          to cmpxchg is not a good idea on many targets as that will force
  17.          expensive memory synchronizations among processors and penalize other
  18.          running threads.
  19.          On the other hand, we do want to update memory state on the local core
  20.          once in a while to avoid spinning indefinitely until some event that
  21.          will happen to update local memory as a side-effect.  */
  22.       if (SPIN_LOCK_READS_BETWEEN_CMPXCHG >= 0)
  23.         {
  24.           int wait = SPIN_LOCK_READS_BETWEEN_CMPXCHG;

  25.           while (*lock != 0 && wait > 0)
  26.             --wait;
  27.         }
  28.       else
  29.         {
  30.           while (*lock != 0)
  31.             ;
  32.         }
  33.     }   
  34.   while (atomic_compare_and_exchange_val_acq (lock, 1, 0) != 0);

  35.   return 0;
  36. }
復(fù)制代碼





歡迎光臨 Chinaunix (http://www.72891.cn/) Powered by Discuz! X3.2