• <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>
            隨筆-159  評論-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 春秋十二月 閱讀(2170) 評論(0)  編輯 收藏 引用 所屬分類: C/C++
            午夜不卡888久久| 国产成人精品久久二区二区| 无码AV中文字幕久久专区| 久久综合九色综合欧美就去吻| 久久精品国产亚洲77777| 亚洲精品国产美女久久久| 少妇久久久久久被弄到高潮| 精品视频久久久久| 国产免费久久久久久无码| 亚洲国产精品人久久| 亚洲午夜精品久久久久久人妖| 国产精品久久久久影院色| 狠狠色丁香久久婷婷综| 国产亚洲婷婷香蕉久久精品| 国产精品久久久久久久久| 国产美女久久久| 国产精品成人久久久久三级午夜电影 | 亚洲国产精品一区二区久久hs| 99精品国产免费久久久久久下载| 亚洲色欲久久久久综合网| 久久久久久伊人高潮影院| 久久国产免费直播| 久久久久亚洲AV无码专区体验| 996久久国产精品线观看| 国产999精品久久久久久| 亚洲精品高清一二区久久| 久久九九久精品国产免费直播| 久久精品国产亚洲AV无码麻豆| 99久久精品国产麻豆| 国产福利电影一区二区三区久久久久成人精品综合 | 久久精品国产69国产精品亚洲| 99久久亚洲综合精品成人| 久久婷婷色综合一区二区| 国产精品久久久久免费a∨| 久久国产精品99精品国产| 狠狠综合久久综合中文88| 精品久久久无码人妻中文字幕| 97久久精品无码一区二区 | 久久久噜噜噜久久中文字幕色伊伊| 日韩久久久久久中文人妻| 国产精品久久久天天影视香蕉 |