• <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>
            隨筆-161  評論-223  文章-30  trackbacks-0
               信號量是一種用于并發環境同步手段的原語,分為無名信號量和有名信號量兩種,前者只能用于線程間同步,而后者還可用于進程間同步。它包括創建、等待、掛出、取值和銷毀5種基本操作。與互斥鎖不同的是:
               ● 信號量擁有一個計數值,表示可用的資源數量,僅當該值為0或1時,則相當于互斥鎖。
               ● 信號量是條件式加鎖,即僅當計數值不大于0時才會鎖住當前線程或進程,而互斥鎖則是無條件。
               ● 信號量的加鎖和解鎖不必是同一線程或進程,而互斥鎖則必須是同一個。
               ● 任何線程或進程都可以掛出一個信號,即使當前沒有線程或進程正在等待該信號值變成正數,而互斥鎖在沒有加鎖后解鎖則會發生錯誤。
               本文展示了基于Posix、PThread、SystemV和Win32四種平臺的封裝實現。

            接口
               所有信號量操作,成功返回0,失敗返回-1,對應的錯誤碼,win32可調用getlasterror獲取,其它平臺則是errno。對于win32平臺的wait和trywait操作,廢棄返回1,超時返回2;因當前沒有獲取信號值的API,sema_getvalue操作簡單地返回-1。   
             1#ifdef _POSIX_SEM
             2#include <semaphore.h>
             3typedef struct 
             4{
             5    union 
             6    {
             7        sem_t* proc_sem_;
             8        sem_t thr_sem_;
             9    }
            ;
            10    char* name_;
            11}
             sema_t;
            12
            13typedef void SECURITY_ATTRIBUTES;
            14
            15#elif defined(_SYSV_SEM)
            16typedef struct 
            17{
            18    int  id_;
            19    char* name_;
            20}
            sema_t;
            21
            22typedef void SECURITY_ATTRIBUTES;
            23
            24#elif defined(_PTHREAD_SEM)
            25#include <pthread.h>
            26typedef struct 
            27{
            28    pthread_cond_t cond_;
            29    pthread_mutex_t lock_;
            30    int value_;
            31}
            sem_t;
            32
            33typedef struct
            34{
            35    union {
            36        sem_t* proc_sem_;
            37        sem_t thr_sem_;
            38    }
            ;
            39    char* name_;
            40}
            sema_t;
            41
            42typedef void SECURITY_ATTRIBUTES;
            43
            44#elif defined(_WIN32_SEM)
            45#include <windows.h>
            46typedef HANDLE sema_t;
            47
            48#else
            49#error Currently only support posix,system v,pthread and win32 semaphore.
            50#endif
            51
            52int sema_init(sema_t* s,const char* name,unsigned int value,unsigned int max,SECURITY_ATTRIBUTES* sa);
            53
            54int sema_wait(sema_t* s);
            55
            56int sema_trywait(sema_t* s);
            57
            58int sema_post(sema_t* s);
            59
            60int sema_getvalue(sema_t*s,int* val);
            61
            62int sema_destroy(sema_t* s);

            實現
              1int sema_init(sema_t* s,const char* name,unsigned int value,unsigned int max,SECURITY_ATTRIBUTES* sa)
              2{
              3#ifdef _POSIX_SEM
              4    if(name){
              5        s->name_ = strdup(name);
              6        if(0==s->name_) 
              7            return -1;
              8        s->proc_sem_ = sem_open(name,O_CREAT,DEFAULT_FILE_PERMS,value);
              9        if(SEM_FAILED==s->proc_sem_) {
             10            free(s->name_);
             11            return -1;
             12        }

             13    }
            else{
             14        if(-1==sem_init(&s->thr_sem_,0,value))
             15            return -1;
             16        s->name_ = 0;
             17    }

             18    return 0;
             19#elif defined(_SYSV_SEM)
             20    if(name){
             21        s->name_ = strdup(name);
             22        if(0==s->name_)
             23            return -1;
             24        if(-1==__sysv_sem_open(&s->id_,name,value)){
             25            free(s->name_);
             26            return -1;
             27        }

             28        return 0;
             29    }
            else{
             30        if(-1==__sysv_init(&s->id_,value))
             31            return -1;
             32        s->name_ = 0;
             33    }

             34    return 0;
             35#elif defined(_PTHREAD_SEM)
             36    if(name){
             37        s->name_ = strdup(name);
             38        if(0==s->name_)
             39            return -1;
             40        s->proc_sem_ = __pthread_sem_open(name,value);
             41        if(0==s->proc_sem_){
             42            free(s->name_);
             43            return -1;
             44        }

             45    }
            else{
             46        if(-1==__pthread_init(&s->thr_sem_,value))
             47            return -1;
             48        s->name_ = 0;
             49    }

             50    return 0;
             51#else
             52    return (*= CreateSemaphoreA(sa,value,max,name)) ? 0 : -1;
             53#endif
             54}

             55
             56int sema_wait(sema_t* s)
             57{
             58#ifdef _POSIX_SEM
             59    sem_t* sem = s->name_ ? s->proc_sem_ : &s->thr_sem_;
             60    return sem_wait(sem);
             61#elif defined(_SYSV_SEM)
             62    struct sembuf op;
             63    int ret;
             64    op.sem_num = 0;
             65    op.sem_op = -1;
             66    op.sem_flg = 0;
             67    return semop(s->id_, &op, 1);
             68#elif defined(_PTHREAD_SEM)
             69    sem_t* sem = s->name_ ? s->proc_sem_ : &s->thr_sem_;
             70
             71    int ret = pthread_mutex_lock(&sem->lock_);
             72    if(ret) {
             73        errno = ret; return -1;
             74    }

             75    while(0==sem->value_)
             76        pthread_cond_wait(&sem->cond_,&sem->lock_);
             77    --sem->value_;
             78    pthread_mutex_unlock(&sem->lock_);
             79
             80    return 0;
             81#else
             82    switch (WaitForSingleObject(*s, INFINITE))
             83    {
             84    case WAIT_OBJECT_0:  return 0;
             85    case WAIT_ABANDONED: return 1;
             86    defaultreturn -1;
             87    }

             88#endif
             89}

             90
             91int sema_trywait(sema_t* s)
             92{
             93#ifdef _POSIX_SEM
             94    sem_t* sem = s->name_ ? s->proc_sem_ : &s->thr_sem_;
             95    return sem_trywait(sem);
             96#elif defined(_SYSV_SEM)
             97    struct sembuf op;
             98    op.sem_num = 0;
             99    op.sem_op = -1;
            100    op.sem_flg = IPC_NOWAIT;
            101    return semop(s->id_, &op, 1);
            102#elif defined(_PTHREAD_SEM)
            103    sem_t* sem = s->name_ ? s->proc_sem_ : &s->thr_sem_;
            104
            105    int ret = pthread_mutex_lock(&sem->lock_);
            106    if(ret) {
            107        errno = ret; return -1;
            108    }

            109    if(0==sem->value_){
            110        ret = -1; errno = EAGAIN;
            111    }
            else {
            112        ret = 0--sem->value_;
            113    }

            114    pthread_mutex_unlock(&sem->lock_);
            115    
            116    return ret;
            117#else
            118    switch (WaitForSingleObject (*s, 0))
            119    {
            120    case WAIT_OBJECT_0:  return 0;
            121    case WAIT_ABANDONED: return 1;
            122    case WAIT_TIMEOUT:   return 2;
            123    defaultreturn -1;
            124    }

            125#endif
            126}

            127
            128int sema_post(sema_t* s)
            129{
            130#ifdef _POSIX_SEM
            131    sem_t* sem = s->name_ ? s->proc_sem_ : &s->thr_sem_;
            132    return sem_post(sem);
            133#elif defined(_SYSV_SEM)
            134    struct sembuf op;
            135    op.sem_num = 0;
            136    op.sem_op = 1;
            137    op.sem_flg = 0;
            138    return semop(s->id_, &op, 1);
            139#elif defined(_PTHREAD_SEM)
            140    sem_t* sem = s->name_ ? s->proc_sem_ : &s->thr_sem_;
            141
            142    pthread_mutex_lock(&sem->lock_);
            143    if(0==sem->value_)
            144        pthread_cond_signal(&sem->cond_);
            145    ++sem->value_;
            146    pthread_mutex_unlock(&sem->lock_);
            147
            148    return 0;
            149#else
            150    return ReleaseSemaphore(*s,1,0? 0 : -1;
            151#endif
            152}

            153
            154int sema_getvalue(sema_t* s,int* val)
            155{
            156#ifdef _POSIX_SEM
            157    sem_t* sem = s->name_ ? s->proc_sem_ : &s->thr_sem_;
            158    return sem_getvalue(sem,val);
            159#elif defined(_SYSV_SEM)
            160    int tmp = semctl(s->id_,0,GETVAL);
            161    if(tmp < 0return -1;
            162    *val = tmp;
            163    return 0;
            164#elif defined(_PTHREAD_SEM)
            165    sem_t* sem = s->name_ ? s->proc_sem_ : &s->thr_sem_;
            166    int ret = pthread_mutex_lock(&sem->lock_);
            167    if(ret){
            168        errno = ret; return -1;
            169    }

            170    *val = sem->value_;
            171    pthread_mutex_unlock(&sem->lock_);
            172#else
            173    return -1;
            174#endif
            175}

            176
            177int sema_destroy(sema_t* s)
            178{
            179#ifdef _POSIX_SEM
            180    if(s->name_){    
            181        sem_unlink(s->name_);
            182        free(s->name_);
            183        if(-1==sem_close(s->proc_sem_))
            184            return -1;
            185    }
            else{
            186        if(-1==sem_destroy(&s->thr_sem_))
            187            return -1;
            188    }

            189    return 0;
            190#elif defined(_SYSV_SEM)
            191    return semctl(s->id_,0,IPC_RMID);
            192#elif defined(_PTHREAD_SEM)
            193    if(s->name_) {
            194        sem_t* sem = s->proc_sem_;
            195
            196        unlink(s->name_);
            197        free(s->name_);
            198        pthread_mutex_destroy(&sem->lock_);
            199        pthread_cond_destroy(&sem->cond_);
            200    
            201        return munmap(sem,sizeof(sem_t));
            202    }
            else {
            203        pthread_mutex_destroy(&s->thr_sem_.lock_);
            204        pthread_cond_destroy(&s->thr_sem_.cond_);
            205    }

            206    return 0;
            207#else
            208    return CloseHandle(*s) ? 0 : -1;
            209#endif
            210}
            posted on 2012-07-20 10:52 春秋十二月 閱讀(2190) 評論(0)  編輯 收藏 引用 所屬分類: C/C++
            久久久久久极精品久久久| 久久久受www免费人成| AV无码久久久久不卡网站下载| 97久久国产露脸精品国产| av无码久久久久不卡免费网站| 国产成人无码精品久久久久免费| 久久久久无码精品国产app| 国产精品99久久久精品无码| 亚洲狠狠综合久久| 久久99久国产麻精品66| 久久综合九色综合精品| 久久精品日日躁夜夜躁欧美| 久久精品成人免费网站| 久久久久青草线蕉综合超碰 | 亚洲va中文字幕无码久久不卡| 国产精品美女久久久m| 亚洲日本va午夜中文字幕久久| 97久久天天综合色天天综合色hd| 伊人 久久 精品| 精品久久久久久久久久中文字幕| 久久国产精品无码HDAV| 久久久精品国产免大香伊 | 久久超碰97人人做人人爱| 久久综合五月丁香久久激情| 久久九九亚洲精品| 久久夜色精品国产欧美乱| 久久精品极品盛宴观看| 久久精品成人一区二区三区| 91精品国产91久久久久久蜜臀| 久久久国产乱子伦精品作者| 狠狠色婷婷久久综合频道日韩 | 成人a毛片久久免费播放| 麻豆AV一区二区三区久久 | 国产91色综合久久免费分享| 色狠狠久久AV五月综合| 伊人久久大香线蕉亚洲| 久久久女人与动物群交毛片| 亚洲AV日韩AV永久无码久久| 天天躁日日躁狠狠久久 | 日日噜噜夜夜狠狠久久丁香五月| 精品国产乱码久久久久久人妻|