2014-01-17 42 views
3

我最近在memcached.h的文件中看到memcached的源代碼。我發現這段代碼:while(pthread_mutex_trylock(mutex))的點是什麼

static inline int mutex_lock(pthread_mutex_t *mutex) 
{ 
    while (pthread_mutex_trylock(mutex)); 
    return 0; 
} 

我只是想知道爲什麼不直接使用pthread_mutex_lock。上述代碼的優點是什麼?

sleep 1 or 2 secondspthread_mutex_trylock看起來更合理,因爲它不會浪費CPU資源。

任何想法?

謝謝。

+1

我會問在[memcached論壇](https://groups.google.com/forum/#!forum/memcached)上,我覺得它是一個錯誤(這在實踐中可能並不重要,因爲它們很少爭用)... –

回答

1

這實質上是螺旋鎖。這個想法是讓線程在內核中避免阻塞,這可能是一個傷害線程效率的操作。

這種自旋鎖只有在鎖的競爭率很低和/或在非常短的時間內保持時纔有意義。很顯然,如果你在while循環中進行了一系列迭代,那也會降低效率。另外,我相信libc通常會在阻塞之前實現pthread_mutex_lock()的一些旋轉,但我必須通過(可能難以閱讀)來源來驗證。另一點 - 這將是非常愚蠢的代碼在一個單一的核心繫統上運行,但是這些代碼正在消失。

+0

在多核系統中使用自旋鎖更有意義。 –

0

這樣你就可以使另一個函數等待資源被解鎖。這也是pthread_mutex_lock所做的。然而,try_lock可能有助於防止死鎖情況,如優先級反轉情況。由於該函數返回一個錯誤而不是阻塞該進程(如pthread_mutex_lock所做的那樣)。

但我同意這基本上實現pthread_mutex_lock,區別在於您可以擴展此自定義函數以防止死鎖。

編輯: 如果您添加幾秒鐘的順時針休眠,可能會發生資源再次被聲明,因爲幾秒鐘是相對較長的時間。通過不增加睡眠時間,可以強制資源被鎖定,因此與等待相比,它更公平。

假設我們有3個線程B,C,D等待由A 鎖定在相同的資源假設我們有1秒的睡眠和的分別B,C,D的到達時間。 0.1, 0.15, 0.2 所有三個線程都需要0.25秒的資源(爲簡單起見),A需要0.1秒。 然後,如果每一個線程需要的資源每一秒,我們可能有情況最終在那裏 A釋放資源在時間1.0,則資源B可以在1.1並釋放在0.35聲稱它,沒有其他線程可以聲稱它,因爲他們是此時正在等待。然後資源A在時間1.9處獲得收益,並再次聲明資源並在2.0處釋放資源。在此之後,線程B再次在時間2.1處聲明。這確保只有資源AB可以聲明資源。因此,我們得到線程CD的飢餓。

當然這是不好的設計,但是在編寫函數來鎖定資源時,應該從使用中抽象出來。但是,使用隨機睡眠可以解決這個問題,但是再次需要關於資源使用的知識。

+0

這個例子很好。但是try_lock如何用來防止死鎖?我知道優先級反轉問題,有一個PTHREAD_PRIO_INHERIT協議可以提高當前持有鎖的線程的優先級。 –

+0

那麼,例如,您可以將此函數用於具有高優先級的線程,因此釋放資源時將立即分配給高優先級任務。或者使用額外的代碼,您可以檢查資源是否可用,以及是否不引發使用該線程的線程(如果該線程的優先級較低)應儘快釋放該資源的標誌。雖然使用普通的'pthread_mutex_lock',這是不可能的,因爲它阻塞。所以基本上你可以用'pthread_mutex_try_lock'來想出你自己的協議。 –

相關問題