POSIX 信號量

POSIX 信號量創(chuàng)建

1笼痹、有名信號量創(chuàng)建

#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <semaphore.h>
       
sem_t *sem_open(const char *name, int oflag,
                       mode_t mode, unsigned int value);

參數(shù)
name: 可訪問的目錄或文件
oflag:if oflag == O_CREAT ,表示如果信號量不存在則創(chuàng)建信號量,存在則不創(chuàng)建; if oflag == O_CREAT|O_EXCL惫东,如果信號量存在,函數(shù)調(diào)用會出錯。
mode:用戶可讀寫權(quán)限
value:初始化值

2廉沮、無名信號量創(chuàng)建

 #include <semaphore.h>

int sem_init(sem_t *sem, int pshared, unsigned int value);

參數(shù)
pshared: if pshared == 0, 表示線程間共享信號量颓遏;if pshared != 0,表示進程間共享信號量滞时。
sem:若是線程間共享信號量叁幢,此值要設(shè)置為全局變量或動態(tài)內(nèi)存(即是線程都可以訪問);若是進程間共享信號量坪稽,此值應(yīng)該在共享內(nèi)存里面(即是進程都可以訪問)曼玩。
value:初始化值。

POSIX 信號量的銷毀

1窒百、有名信號量的銷毀

#include <semaphore.h>

int sem_close(sem_t *sem);

如果進程沒有調(diào)用sem_close 就退出演训, 那么內(nèi)核會將自動關(guān)閉任何打開的信號量。但是信號量的值不會改變贝咙,也就是說內(nèi)核沒有SEM_UNDO的功能,不能自動銷毀信號量拂募。

#include <semaphore.h>

int sem_unlink(const char *name);

如果沒有打開的信號量引用庭猩,則信號量會被銷毀;否則該信號量會延時到最后一個打開的引用關(guān)閉陈症。

2蔼水、無名信號量的銷毀

#include <semaphore.h>

int sem_destroy(sem_t *sem);

一般使用在資源回收階段,若是有進程或線程在占用這個型號量录肯,就釋放信號量趴腋,會出現(xiàn)未定義行為。執(zhí)行了這個函數(shù)论咏,需要使用sem_init才能再次使用信號量优炬。

POSIX 信號量的修改

1、信號量計數(shù)減 1

#include <semaphore.h>

int sem_wait(sem_t *sem);

int sem_trywait(sem_t *sem);

int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

man page

DESCRIPTION
       sem_wait() decrements (locks) the semaphore pointed to by sem.  If the semaphore's value is greater than zero, then the decrement proceeds, and the function returns, immediately.  If the semaphore currently has the value zero, then the call blocks until either it becomes possible to perform the  decrement (i.e., the semaphore value rises above zero), or a signal handler interrupts the call.

       sem_trywait()  is  the  same  as sem_wait(), except that if the decrement cannot be immediately performed, then call returns an error (errno set to  EAGAIN) instead of blocking.

       sem_timedwait() is the same as sem_wait(), except that abs_timeout specifies a limit on the amount of time that the call should block if the decre‐ment cannot be immediately performed.  The abs_timeout argument points to a structure that specifies an absolute timeout in seconds and nanoseconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).  This structure is defined as follows:

           struct timespec {
               time_t tv_sec;      /* Seconds */
               long   tv_nsec;     /* Nanoseconds [0 .. 999999999] */
           };

       If the timeout has already expired by the time of the call, and the semaphore could not be locked immediately, then sem_timedwait()  fails  with  a timeout error (errno set to ETIMEDOUT).

       If the operation can be performed immediately, then sem_timedwait() never fails with a timeout error, regardless of the value of abs_timeout.  Fur‐ thermore, the validity of abs_timeout is not checked in this case.

2厅贪、信號量計數(shù)加 1

#include <semaphore.h>

int sem_post(sem_t *sem);

API封裝

sem.h

#ifndef _SEM_H
#define _SEM_H

#include <semaphore.h>
#include <fcntl.h>
#include <time.h>

sem_t  * Sem_Open(const char *name, int oflag, mode_t mode, unsigned int value);

int Sem_Close(sem_t *sem);
int Sem_Unlink(const char *name);

int Sem_Trywait(sem_t *sem);
int Sem_Wait(sem_t *sem);
int Sem_Timedwait(sem_t *sem, const struct timespec *pstTime);

int Sem_Post(sem_t *sem);

int Sem_Init(sem_t *sem, int pshared, unsigned int value);

int Sem_Destroy(sem_t *sem);

#endif

sem.c

#include "sem.h"
#include <stdio.h>
#include <errno.h>

sem_t * Sem_Open(const char *name, int oflag, mode_t mode, unsigned int value)
{
    sem_t *sem = NULL;
    sem = sem_open(name, oflag, mode, value);
    if(SEM_FAILED == sem)
    {
        perror("sem_open:");
    }

    return sem;
}


int Sem_Close(sem_t *sem)
{
    int val = sem_close(sem);

    if(val < 0)
    {
        perror("sem_close error:");
    }

    return val;
}


int Sem_Unlink(const char *name)
{
    int val = sem_unlink(name);
    if(val < 0)
    {
        perror("sem_unlink error:");
    }

    return val;
}


int Sem_Trywait(sem_t *sem)
{
    return sem_trywait(sem);
}


int Sem_Wait(sem_t *sem)
{
    int val = 0;
    val = sem_wait(sem);
    if(val < 0)
    {
        perror("sem_wait error:");
    }

    return val;
}


int Sem_Timedwait(sem_t *sem, const struct timespec *pstTime)
{
    int val = 0;

    val = sem_timedwait(sem, pstTime);
    if(val < 0)
    {
        perror("sem_timedwait error:");
    }

    return val;
}


int Sem_Post(sem_t *sem)
{
    return sem_post(sem);
}


int Sem_Init(sem_t *sem, int pshared, unsigned int value)
{
    int val = sem_init(sem, pshared, value);
    if(val < 0)
    {
        perror("sem_init error:");
    }
    return val;
}


int Sem_Destroy(sem_t *sem)
{
    printf("Sem_Destroy\n");
    int val = sem_destroy(sem);
    if(val < 0)
    {
        perror("sem_destroy error:");
    }

    return val;
}


例程

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdlib.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/stat.h>

#include "sem.h"

int main(void)
{
    sem_t *sem;

    sem_t ss_sem;
    int shmid;
    key_t key = ftok("/usr", 0x01);
    if(key < 0)
    {
            perror("ftok  error");
    }

    shmid = shmget(key, sizeof(sem_t), IPC_CREAT| 0666);
    if(shmid < 0)
    {
            perror("shmget error");
    }

    sem_t * mm = (sem_t *)shmat(shmid, 0, 0);
    if(NULL == mm)
    {
        perror("shmat error");
    }

    Sem_Init((sem_t *)mm, 1, 1);
    pid_t pid = 0;

    Sem_Unlink("/home");
    Sem_Unlink("/usr");
    pid = fork();

    if(0 == pid)
    {
        key_t key = ftok("/home", 0x01);
        if(key < 0)
        {
                perror("ftok  error");
        }

        shmid = shmget(key, sizeof(sem_t), IPC_CREAT| 0666);
        sem_t * mm = (sem_t *)shmat(shmid, 0, 0);
        sem = Sem_Open("/usr", O_CREAT, 0666, 1);
        
        while(1)
        {
            //Sem_Wait(sem);
            Sem_Wait(mm);
            fprintf(stderr,"===> child process\n");

            usleep(3000000);
            Sem_Post(mm);
            //Sem_Post(sem);

        }

    }

    //sem = Sem_Open("/usr", O_CREAT, 0666, 1);
    int count = 0;
    struct timespec tm;

    while(1)
    {
        clock_gettime(CLOCK_REALTIME, &tm);
        tm.tv_sec += 2;

        //Sem_Wait(sem);
        //Sem_Wait(mm);
        if(Sem_Timedwait(mm, &tm) == 0)
        {
            fprintf(stderr, "###parent process\n");
            Sem_Post(mm);
        }
        //Sem_Post(mm);
        //Sem_Post(sem);
        usleep(300000);
    }

    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蠢护,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子养涮,更是在濱河造成了極大的恐慌葵硕,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贯吓,死亡現(xiàn)場離奇詭異懈凹,居然都是意外死亡,警方通過查閱死者的電腦和手機悄谐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門介评,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人尊沸,你說我怎么就攤上這事威沫∠凸撸” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵棒掠,是天一觀的道長孵构。 經(jīng)常有香客問我,道長烟很,這世上最難降的妖魔是什么颈墅? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮雾袱,結(jié)果婚禮上恤筛,老公的妹妹穿的比我還像新娘。我一直安慰自己芹橡,他們只是感情好毒坛,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著林说,像睡著了一般煎殷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上腿箩,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天豪直,我揣著相機與錄音,去河邊找鬼珠移。 笑死弓乙,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的钧惧。 我是一名探鬼主播暇韧,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼垢乙!你這毒婦竟也來了锨咙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤追逮,失蹤者是張志新(化名)和其女友劉穎酪刀,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钮孵,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡骂倘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了巴席。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片历涝。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出荧库,到底是詐尸還是另有隱情堰塌,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布分衫,位于F島的核電站场刑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蚪战。R本人自食惡果不足惜牵现,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望邀桑。 院中可真熱鬧瞎疼,春花似錦、人聲如沸壁畸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捏萍。三九已至竿裂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間照弥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工进副, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留这揣,地道東北人。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓影斑,卻偏偏與公主長得像给赞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子矫户,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容