青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

大龍的博客

常用鏈接

統(tǒng)計(jì)

最新評(píng)論

unix---線程同步 --- 轉(zhuǎn)

寫在前面

 

1.          本文內(nèi)容對(duì)應(yīng)《UNIX環(huán)境高級(jí)編程》(第2版)》第11章。

2.          總結(jié)了線程同步的三種方法:互斥量、讀寫鎖以及條件變量。

3.          希望本文對(duì)您有所幫助,也歡迎您給我提意見(jiàn)和建議。

線程同步是一個(gè)老話題了。當(dāng)多個(gè)控制線程共享相同的內(nèi)存時(shí),需要確保每個(gè)線程看到一致的數(shù)據(jù)視圖。APUE介紹的線程同步方式有:

 


--------------------------------------------------------------------------------

互斥量

 

互斥量(mutex)從本質(zhì)上說(shuō)是一把鎖,在訪問(wèn)共享資源前對(duì)互斥量進(jìn)行加鎖,在訪問(wèn)完成后釋放互斥量上的鎖。互斥變量用pthread_mutex_t數(shù)據(jù)類型來(lái)表示,在使用前必須對(duì)其進(jìn)行初始化。對(duì)于靜態(tài)分配的互斥量,可以把它設(shè)置為常量PTHREAD_MUTEX_INITIALIZER。如果動(dòng)態(tài)地分配互斥量,可以通過(guò)調(diào)用pthread_mutex_init函數(shù)進(jìn)行初始化,并且在釋放內(nèi)存前需要調(diào)用pthread_mutex_destroy。當(dāng)參數(shù)attr置為NULL時(shí),使用默認(rèn)的屬性初始化互斥量。

#include <pthread.h>

int pthread_mutex_init(pthread_mutex_t *restrict mutex,

                       const pthread_mutexattr_t *restrict attr);

int pthread_mutex_destroy(pthread_mutex_t *mutex);

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

                                         All return: 0 if OK, error number on failure
 

對(duì)互斥量加鎖需要調(diào)用pthread_mutex_lock,如果互斥量已經(jīng)上鎖,調(diào)用線程將阻塞直到互斥量被解鎖。對(duì)互斥量解鎖,需要調(diào)用pthread_mutex_unlock。如果線程不希望被阻塞,它可以使用pthread_mutex_trylock嘗試對(duì)互斥量進(jìn)行加鎖。如果調(diào)用pthread_mutex_trylock時(shí)互斥量處于未鎖住狀態(tài),那么pthread_mutex_trylock將鎖住互斥量,不會(huì)出現(xiàn)阻塞并返回0,否則pthread_mutex_trylock就會(huì)失敗,不能鎖住互斥量,而返回EBUSY。

如果線程試圖對(duì)同一個(gè)互斥量加鎖兩次,那么它自身就會(huì)陷入死鎖狀態(tài)。可以通過(guò)小心地控制互斥量加鎖的順序來(lái)避免死鎖的發(fā)生。只有一個(gè)線程試圖以與另一個(gè)線程相反的順序鎖住互斥量時(shí),才可能出現(xiàn)死鎖。如果無(wú)法控制互斥量加鎖的順序,可以在試圖加鎖時(shí),先釋放占有的鎖,然后過(guò)段時(shí)間再試。

 


--------------------------------------------------------------------------------

讀寫鎖

 

讀寫鎖與互斥量類似,不過(guò)讀寫鎖允許更高的并行性。讀寫鎖可以有三種狀態(tài):讀模式下加鎖狀態(tài),寫模式下加鎖狀態(tài),以及不加鎖狀態(tài)。一次只有一個(gè)線程可以占有寫模式的讀寫鎖,但是多個(gè)線程可以同時(shí)占有讀模式的讀寫鎖。因此,讀寫鎖也叫做共享-獨(dú)占鎖。讀寫鎖非常適用于對(duì)數(shù)據(jù)結(jié)構(gòu)讀的次數(shù)遠(yuǎn)大于寫的情況。

         與互斥量一樣,讀寫鎖在使用之前必須初始化,在釋放它們底層的內(nèi)存前必須銷毀。這通過(guò)pthread_rwlock_inti和pthread_rwlock_destroy函數(shù)完成。如果希望讀寫鎖有默認(rèn)的屬性,可以傳一個(gè)空指針給attr。要在讀模式下鎖定讀寫鎖,需要調(diào)用pthread_rwlock_rdlock;要在寫模式下鎖定讀寫鎖,需要調(diào)用pthread_rwlock_wrlock。不管以何種方式鎖住讀寫鎖,都可以調(diào)用pthread_rwlock_unlock進(jìn)行解鎖。如果希望線程不被阻塞,可以調(diào)用pthread_rwlock_tryrdlock和pthread_rwlock_trywrlock函數(shù)嘗試對(duì)讀寫鎖進(jìn)行加鎖。

#include <pthread.h>

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,

                        const pthread_rwlockattr_t *restrict attr);

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

                                         All return: 0 if OK, error number on failure
 

 


--------------------------------------------------------------------------------

條件變量

 

條件變量與互斥量一起使用時(shí),允許線程以無(wú)競(jìng)爭(zhēng)的方式等待特定的條件發(fā)生。條件本身是由互斥量保護(hù)的,線程在改變條件前必須首先鎖住互斥量,且只有在鎖住互斥量以后才能計(jì)算條件。條件變量使用之前必須首先進(jìn)行初始化,pthread_cond_t數(shù)據(jù)類型代表的條件變量可以用兩種方式初始化。可以把常量PTHREAD_COND_INITIALIZER賦給靜態(tài)分配的條件變量,但是如果條件變量是動(dòng)態(tài)分配的,可以使用pthread_cond_init函數(shù)進(jìn)行初始化。在釋放底層的內(nèi)存空間前,可以使用pthread_mutex_destroy函數(shù)對(duì)條件變量進(jìn)行銷毀。除非需要?jiǎng)?chuàng)建一個(gè)非默認(rèn)屬性的條件變量,否則pthread_cond_init函數(shù)的attr參數(shù)可以設(shè)置為NULL。

#include <pthread.h>

int pthread_cond_init(pthread_cond_t *restrict cond,

                      pthread_condattr_t *restrict attr);

int pthread_cond_destroy(pthread_cond_t *cond);                                        

All return: 0 if OK, error number on failure
 

使用pthread_cond_wait等待條件變?yōu)檎妫绻诮o定時(shí)間內(nèi)條件不能滿足,那么會(huì)生成一個(gè)代表出錯(cuò)碼的返回值。調(diào)用者需要把鎖住的互斥量傳給pthread_cond_wait對(duì)條件進(jìn)行保護(hù)。函數(shù)把調(diào)用線程放到等待條件的線程列表上,然后對(duì)互斥量解鎖,這兩個(gè)操作是原子操作。當(dāng)pthread_cond_wait返回時(shí),互斥量再次被鎖住。

#include <pthread.h>

int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);

int pthread_cond_timedwait(pthread_cond_t *restrict cond,

                           pthread_mutex_t *restrict mutex,

                           const struct timespec *restrict timeout);                        

All return: 0 if OK, error number on failure
 

pthread_cond_timedwait函數(shù)的工作方式與pthread_cond_wait函數(shù)相似。timeout值指定了等待的時(shí)間,它通過(guò)timespec結(jié)構(gòu)指定。時(shí)間值用秒數(shù)或者分秒數(shù)表示,分秒數(shù)的單位是納秒。時(shí)間值是一個(gè)絕對(duì)數(shù)而不是相對(duì)數(shù)。可以使用gettimeofday獲取用timeval結(jié)構(gòu)表示的當(dāng)前時(shí)間,然后把這個(gè)時(shí)間加上要等待的時(shí)間轉(zhuǎn)換成timespec結(jié)構(gòu)。

struct timespec {

        time_t tv_sec;   /* seconds */

        long   tv_nsec;  /* nanoseconds */

};

 

void maketimeout(struct timespec *tsp, long minutes)

{

        struct timeval now;

        /* get the current time */

        gettimeofday(&now);

        tsp->tv_sec = now.tv_sec;

        tsp->tv_nsec = now.tv_usec * 1000; /* usec to nsec */

        /* add the offset to get timeout value */

        tsp->tv_sec += minutes * 60;

}
 

         如果時(shí)間值到了但是條件還沒(méi)有出現(xiàn),pthread_cond_timedwait將重新獲取互斥量,然后返回錯(cuò)誤ETIMEDOUT。從pthread_cond_wait或者pthread_cond_timedwait調(diào)用成功返回時(shí),線程需要重新計(jì)算條件,因?yàn)槠渌€程可能已經(jīng)在運(yùn)行并改變了條件。

pthread_cond_signal函數(shù)將喚醒等待該條件的某個(gè)線程,而pthread_cond_broadcast函數(shù)將喚醒等待該條件的所有線程。必須注意一定要在改變條件狀態(tài)以后再喚醒等待線程。

#include <pthread.h>

int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);                    

All return: 0 if OK, error number on failure
 

         使用范例如下:

#include <pthread.h>

 

struct msg {

    struct msg *m_next;

    /* ... more stuff here ... */

};

struct msg *workq;

pthread_cond_t qready = PTHREAD_COND_INITIALIZER;   /*初始化條件變量*/

pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;  /*初始化互斥量*/

 

void process_msg(void)

{

    struct msg *mp;

 

    for (;;) {

        pthread_mutex_lock(&qlock);     /*條件本身由互斥量保護(hù)*/

        while (workq == NULL)           /*wait返回后要重新檢查條件*/

            pthread_cond_wait(&qready, &qlock);  /*wait期間釋放互斥量,返回時(shí)再次鎖住*/

        mp = workq;

        workq = mp->m_next;

        pthread_mutex_unlock(&qlock);   /*真正釋放互斥量*/

        /* now process the message mp */

    }

}

 

void enqueue_msg(struct msg *mp)

{

    pthread_mutex_lock(&qlock);       /*修改條件前鎖住互斥量*/

    mp->m_next = workq;

    workq = mp;

    pthread_mutex_unlock(&qlock);

pthread_cond_signal(&qready);     /*喚醒等待線程時(shí)不需要占有互斥量*/

/*如果希望在wait返回時(shí)不用再檢查條件,

就需要在喚醒時(shí)占有互斥量*/

}
 


本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/intrepyd/archive/2009/08/20/4467821.aspx

posted on 2010-01-04 15:43 大龍 閱讀(682) 評(píng)論(0)  編輯 收藏 引用


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧美日韩在线综合| 女生裸体视频一区二区三区| 久久久久网址| 亚洲国产91色在线| 欧美日韩国产探花| 久久久精品国产一区二区三区| 亚洲高清毛片| 久久亚洲春色中文字幕| 亚洲高清久久网| 久久全国免费视频| 亚洲综合色自拍一区| 国产一区二区在线免费观看| 欧美日韩亚洲一区二区三区在线 | 欧美日韩ab| 国产精品久久久久影院色老大| 老司机一区二区| 美女福利精品视频| 亚洲精品乱码久久久久久按摩观 | 欧美在线视频不卡| 香蕉久久一区二区不卡无毒影院 | 亚洲国产精品视频| 99精品视频免费全部在线| 亚洲欧美在线磁力| 欧美黄色免费网站| 亚洲欧美在线视频观看| 欧美专区日韩视频| 欧美日韩在线精品一区二区三区| 国产一区高清视频| 亚洲午夜电影网| 久久久久久久激情视频| 中文有码久久| 欧美激情一区二区三级高清视频| 国产情人节一区| 亚洲午夜精品久久| 欧美黄色小视频| 欧美自拍丝袜亚洲| 欧美性一区二区| 亚洲一区国产视频| 一本色道久久综合狠狠躁篇的优点| 久久全球大尺度高清视频| 国产午夜精品美女毛片视频| 亚洲一区二区免费看| 99精品视频一区二区三区| 欧美精品福利| 亚洲免费视频一区二区| 亚洲午夜小视频| 亚洲一区二区三区免费视频| 国产精品国产三级国产专区53| 亚洲午夜精品福利| 亚洲影音一区| 亚洲丶国产丶欧美一区二区三区| 久久中文久久字幕| 免费在线播放第一区高清av| 亚洲欧洲视频在线| 亚洲高清在线精品| 欧美日韩中文精品| 久久久久久亚洲精品不卡4k岛国| 久久精品国产99精品国产亚洲性色 | 国产日产欧产精品推荐色 | 亚洲区在线播放| 亚洲成色www8888| 国产精品无码专区在线观看 | 欧美日韩在线三区| 亚洲欧美日本国产专区一区| 午夜一区二区三区在线观看| 在线成人h网| 亚洲欧美伊人| 亚洲欧美一区二区原创| 欧美日韩精品福利| 欧美成人dvd在线视频| 国产欧美 在线欧美| 一区二区三区三区在线| 91久久精品国产91久久性色tv| 亚洲欧美日韩国产另类专区| 中文亚洲欧美| 欧美日韩另类一区| 一本久久精品一区二区| 亚洲六月丁香色婷婷综合久久| 午夜久久久久久| 欧美日韩中文字幕日韩欧美| 亚洲精品一区二区三区不| 亚洲日本在线观看| 欧美理论在线| 亚洲天堂偷拍| 久久精品视频在线播放| 黄色av日韩| 久久久精品动漫| 亚洲国产精品精华液2区45| 亚洲精品国精品久久99热一| 欧美日韩国产大片| 亚洲综合精品四区| 久久视频在线免费观看| 在线不卡欧美| 国产精品区免费视频| 欧美伊人久久| 亚洲人成人一区二区三区| 西西人体一区二区| 影音国产精品| 国产日韩欧美精品一区| 女人天堂亚洲aⅴ在线观看| 亚洲美女毛片| 午夜久久电影网| 日韩一区二区精品视频| 国产综合色一区二区三区 | 亚洲国产精品久久| 久久成年人视频| 亚洲欧美精品伊人久久| 日韩一级在线| 亚洲免费观看高清完整版在线观看熊| 国产精品毛片| 国产精品午夜在线观看| 国产精品高清在线| 欧美日韩岛国| 国产精品久久久久婷婷| 欧美精品在线免费| 你懂的网址国产 欧美| 欧美一区二区三区视频免费播放| 亚洲国产精品悠悠久久琪琪 | 久久久久久久999| 亚洲欧美在线看| 久久国产精品久久久| 久久国产精品久久久久久| 久久精品国产清高在天天线| 久久久久一区| 欧美女主播在线| 欧美日韩亚洲一区三区| 欧美日韩在线播放| 国产亚洲免费的视频看| 亚洲精品久久在线| 欧美专区福利在线| 欧美高清视频一区二区三区在线观看| 欧美成人免费播放| 一区二区免费在线观看| 欧美亚洲综合网| 欧美日韩国产色综合一二三四 | 在线国产亚洲欧美| 亚洲人屁股眼子交8| 亚洲一级片在线看| 久久午夜影视| 亚洲一区二区影院| 久久精品视频网| 国产精品国内视频| 亚洲国产影院| 久久天天躁狠狠躁夜夜av| 亚洲高清三级视频| 久久男女视频| 国产一区二区三区四区在线观看 | 亚洲图片在区色| 亚洲一区二区三区免费在线观看| 亚洲福利视频三区| 亚洲欧美日韩另类| 欧美视频你懂的| 99视频一区二区三区| 91久久精品国产91久久性色| 久久视频一区二区| 国内精品一区二区| 欧美一区二区私人影院日本| 一本色道久久综合亚洲精品高清 | 亚洲视频精选| 国产精品都在这里| 亚洲欧美日韩一区在线| 亚洲一区二区成人在线观看| 欧美四级在线观看| 欧美一级大片在线观看| 亚洲视频在线观看视频| 国产欧美另类| 欧美激情a∨在线视频播放| 欧美精品久久99| 宅男噜噜噜66一区二区| 亚洲综合不卡| 亚洲激情电影在线| 一区二区三区导航| 国产综合色产在线精品| 欧美高清一区| 国产精品国码视频| 乱中年女人伦av一区二区| 欧美成人中文字幕在线| 性感少妇一区| 欧美激情黄色片| 久久久久久91香蕉国产| 欧美片第1页综合| 免费成人美女女| 国产精品嫩草99a| 最新国产成人在线观看| 国产一区999| 亚洲欧美精品在线观看| 日韩午夜电影| 欧美激情 亚洲a∨综合| 久久午夜国产精品| 国产精品尤物福利片在线观看| 欧美黄在线观看| 亚洲精品社区| 久久综合国产精品台湾中文娱乐网| 欧美成人免费va影院高清| 激情偷拍久久| 免费观看成人网| 国产亚洲欧洲997久久综合| 亚洲在线观看免费视频| 亚洲人成在线免费观看| 国产老女人精品毛片久久|