久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

線程同步與互斥鎖

 印度阿三17 2019-05-31

相比多進程模型,,多線程模型最大的優(yōu)勢在于數(shù)據(jù)共享非常方便,同一進程內(nèi)的多個線程可以使用相同的地址值訪問同一塊內(nèi)存數(shù)據(jù),。但是,,當多個線程對同一塊內(nèi)存數(shù)據(jù)執(zhí)行“讀?處理?更新”操作時,會由于線程的交叉執(zhí)行而造成數(shù)據(jù)的錯誤,。

例如以下代碼段,,當 thread_func() 同時在多個線程中執(zhí)行時,更新到 glob_value 中的值就會互相干擾,,產(chǎn)生錯誤結(jié)果,。

#define LOOP_COUNT   1000000
int glob_value = 0;

void * thread_func(void * args)
{
    int counter = 0;
    while(counter   < LOOP_COUNT)
    {
        int local = glob_value;
        local  ;
        glob_value = local;
    }
}

解決這類問題的關鍵在于,當一個線程正在執(zhí)行“讀?處理?更新”操作時,,保證其他線程不會中途闖入與其交叉執(zhí)行,。不可被打斷的執(zhí)行序列稱為臨界區(qū),保證多個線程不會交叉執(zhí)行同一臨界區(qū)的技術稱為線程同步,。

1 互斥鎖的使用

最常用的線程同步技術是互斥鎖,,Linux 線程庫中的相關函數(shù)有:

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);

這里pthread的p代表POSIX線程

所有線程都有一個線程號,也就是Thread ID,。其類型為pthread_t,。通過調(diào)用pthread_self()函數(shù)可以獲得自身的線程號。

pthread_mutex_lock() 負責在進入臨界區(qū)之前對臨界區(qū)加鎖,;
pthread_mutex_unlock() 負責在執(zhí)行完臨界區(qū)處理時給臨界區(qū)解鎖,。

當某個線程試圖給一個已經(jīng)處在加鎖狀態(tài)的臨界區(qū)再次加鎖時,,該線程就會被臨時掛起,一直等到該臨界區(qū)被解鎖后,,才會被喚醒并繼續(xù)執(zhí)行,。

如果同時有多個線程等待某個臨界區(qū)解鎖,那下次被喚醒的進程取決于內(nèi)核的調(diào)度策略,,并沒有固定的順序,。

靜態(tài)分配的 mutex 變量在使用之前應該被初始化為 PTHREAD_MUTEX_INITIALIZER,而動態(tài)分配的 mutex 需要調(diào)用 pthread_mutex_init() 進行初始化,,且只被某個線程初始化一次,,可以利用 pthread_once() 函數(shù)方便完成。

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));

多個線程在臨界區(qū)上的執(zhí)行是串行的,,開發(fā)者應該盡量減少程序在臨界區(qū)內(nèi)的停留時間,,以提高程序的并行性。因此,,臨界區(qū)不應該包含任何非必須的邏輯,,以及任何可能帶來高延遲的 IO 等操作

2 互斥鎖的保護范圍和使用順序

對互斥鎖加鎖的不恰當使用會造成線程的死鎖,比如下面這兩種情況,。

  1. 典型的情況是,,兩個線程執(zhí)行時都需要鎖定互斥鎖 A 和 B,在一個線程中,,鎖定順序是先鎖定 A,,后鎖定 B,而另一個線程的鎖定順序是先鎖定 B,,再鎖定 A,。這種情況下,當一個線程已經(jīng)鎖定了 A 而另一個線程恰好鎖定了 B 時,,雙方因互相爭用對方已鎖定的互斥鎖,,誰也不讓步,而陷入死鎖狀態(tài),。
  1. 另一種情況是,,一個線程已經(jīng)鎖定了互斥鎖 A,但在其后的處理邏輯中試圖再次鎖定 A,,這時該線程會讓自己陷入睡眠狀態(tài),,再也等不到被喚醒的時候。

因此,,開發(fā)者需要仔細規(guī)劃互斥鎖保護范圍和使用順序

3 避免死鎖的兩個加鎖函數(shù)

為了避免出現(xiàn)死鎖問題,,可以使用另外兩種變體的鎖定函數(shù),如下所示:

int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict abs_timeout);

前者可以在鎖定失敗后立即返回,后者可以在一段超時時間后返回,,

應用這兩個函數(shù)可以處理這種錯誤情況,,而避免陷入無限的死鎖中。

在 Linux 中,,實現(xiàn)互斥鎖采用的是 Futex(Fast Userspace Mutex)方案,。在該實現(xiàn)中,只有發(fā)生了鎖的爭用才需要陷入到內(nèi)核空間中處理,,否則所有的操作都可以在用戶空間內(nèi)快速完成,。在大多數(shù)情況下,互斥鎖本身的效率很高,,其平均開銷大約相當于幾十次內(nèi)存讀寫和算數(shù)運算所花費的時間,。

來源:http://www./content-4-220351.html

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多