信号灯/信号量(semaphore)

一、概念

        是不同进程间或一个给定进程内部不同线程间同步的机制。类似我们的PV 操作概念:
生产者和消费者场景

P(S) 含义如下:

if (信号量的值大于 0) {
    申请资源的任务继续运行;
    信号量的值减一;
} else {
    申请资源的任务阻塞;
}
    V(S) 含义如下:
    信号量的值加一;
if (有任务在等待资源) {
    唤醒等待的任务,让其继续运行
}

三种信号灯:
        Posix 有名信号灯
        Posix 无名信号灯 (linux 只支持线程同步)
        System V 信号灯
        Posix 有名信号灯和无名信号灯使用:

 

有名信号灯打开:

sem_t *sem_open(const char *name, int oflag);

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

参数:

        name:name 是给信号灯起的名字
        oflag:打开方式,常用 O_CREAT
        mode:文件权限。常用 0666
        value:信号量值。二元信号灯值为 1,普通表示资源数目

信号灯文件位置:/dev/shm

有名信号灯关闭

        int sem_close(sem_t *sem);

有名信号灯的删除

        int sem_unlink(const char* name);

无名信号灯初始化

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

参数:

sem:需要初始化的信号灯变量

shared: shared 指定为 0,表示信号量只能由初始化这个信号量的进程使用,不能在进程间使
用,linux 不支持进程间同步。

Value:信号量的值

无名信号灯销毁

        int sem_destroy(sem_t* sem);

信号灯 P 操作

        int sem_wait(sem_t *sem);

        获取资源,如果信号量为 0,表示这时没有相应资源空闲,那么调用线程就将挂起,直到有

空闲资源可以获取

信号灯 V 操作

int sem_post(sem_t *sem);

        释放资源,如果没有线程阻塞在该 sem 上,表示没有线程等待该资源,这时该函数就对信
号量的值进行增 1 操作,表示同类资源多增加了一个。如果至少有一个线程阻塞在该 sem上,表示有线程等待资源,信号量为 0,这时该函数保持信号量为 0 不变,并使某个阻塞在该 sem 上的线程从 sem_wait 函数中返回

注意:编译 posix 信号灯需要加 pthread 动态库。

System V 信号灯使用:

        int semget(key_t key, int nsems, int semflg);

功能:创建/打开信号灯

参数:key:ftok 产生的 key 值(和信号灯关联的 key 值)

nsems:信号灯集中包含的信号灯数目

semflg:信号灯集的访问权限,通常为 IPC_CREAT |0666

返回值:成功:信号灯集 ID ; 失败:-1

int semop ( int semid, struct sembuf *opsptr, size_t nops);

功能:对信号灯集合中的信号量进行 P - V 操作

参数:semid:信号灯集 ID

struct sembuf {
    short sem_num; // 要操作的信号灯的编号
    short sem_op; // 1 : 释放资源,V 操作
    // -1 : 分配资源,P 操作
    short sem_flg; // 0(阻塞),IPC_NOWAIT, SEM_UNDO
};//对某一个信号灯的操作,如果同时对多个操作,则需要定义这种结构体数组

nops: 要操作的信号灯的个数 ,1 个

返回值:成功 :0 ; 失败:-1

        int semctl ( int semid, int semnum, int cmd.../*union semun arg*/);

        功能:信号灯集合的控制(初始化/删除)

        参数:semid:信号灯集 ID

        semnum: 要操作的集合中的信号灯编号

cmd:

        GETVAL:获取信号灯的值,返回值是获得值

        SETVAL:设置信号灯的值,需要用到第四个参数:共用体

        IPC_RMID:从系统中删除信号灯集合

        返回值:成功 0 ; 失败 -1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值