【Linux】进程间通信--信号量

一、信号量原理

        进程间同步和互斥的核心机制 <sys/sem.h>

        信号量是一个特殊的变量,一般取正数值。它的值代表允许访问的资源数目,获取资源时,需要对信号量的值进行原子减一,该操作被称为 P 操作。当信号量值为 0 时,代表没有资源可用,P 操作会阻塞。释放资源时,需要对信号量的值进行原子加一,该操作被称为 V 操作。信号量主要用来同步进程。信号量的值如果只取 0,1,将其称为二值信号量。如果信号量的值大于 1,则称之为计数信号量。

        本质是一个受保护的整数变量,只能通过原子操作(不可中断的操作)修改值。

        临界资源:同一时刻,只允许被一个进程或线程访问的资源。

        临界区:访问临界资源的代码段。

        原子操作:对信号量的增加或减少,避免多进程并发修改不一致

        阻塞机制:当信号量的值为0时,试图获取资源的进程会被阻塞,直到有其他进程释放资源

        两种类型:

二值信号量计数信号量
0        10 ~ n

        核心操作:P  V原语  Proberen  Verhogen

        p操作:将信号量值减一,如果>=0,进程可继续执行,如果<0,进程阻塞,放入信号量的等待队列。

        V操作:将信号量值加一,如果>0,进程执行,如果<=0,从等待队列中唤醒一个进程,继续执行。

        P操作获取资源   V操作释放资源

        使用信号量的步骤:

        a.创建并初始化

        b.进行PV操作

        c.销毁信号量

二、参数介绍

1.semget(): 创建或获取信号量集的系统调用

        成功返回信号量ID,失败返回-1。

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

key: 键值,用于表示信号量集的唯一性。两个进程使用相同key,可以使用同一信号量。

nsems: 要创建的信号量的数量,内核维护的是一个信号量集。

        如果要创建新信号量集,该值需要大于0,如果获取已存在的信号量,可设为0。

semflg: 控制函数行为

        IPC_CREAT: 创建信号量集,如果存在返回0。

        IPC_EXCL: 确保全新创建。

        权限标志:0600。

2.semctl(): 控制信号量集的操作

        int semctl(int semid, int semnum, int op, ...)

semid: 信号量集标识符。

semnum: 信号量集的索引,表示要操作哪一个信号。

        如果对整个信号量集操作,此参数设为0。

op: 要执行的控制命令,决定函数功能。

        SETVAL: 设置semnum指定的信号量的初始值,需配合第四个参数使用。

        GETVAL: 获取semnum指定的信号量的当前值。

        IPC_RMID: 删除整个信号量集。

        IPC_STAT: 获取信号量集的状态信息(创建时间)。

        IPC_SET: 设置信号量集的属性(权限)。

        第四个参数一般需要传递一个nuion semnum类型的参数。

        union semun

                {

                        int val;

                        struct semid_ds *buf;

                        unsigned short *array;

                        struct seminfo *_buf;

                };

3.semop():执行信号量操作,实现对信号量的原子性增减(PV操作)

        int semop(int semid, struct sembuf *sops, unsigned nsops);

semid:信号量的标识符。

sops:指向结构体的指针,定义信号量的操作。

        struct sembuf
        {

                unsigned short sem_num  信号量在集中索引

                short sem_op  操作类型(+1  -1)

                short sem_flg  操作标志,一般用SEM_UNDO(进程退出时自动回复信号量值)

        }

nspos:数组中元素的数量。
 

三、代码练习

        1.例题:进程 a 和进程 b 模拟访问打印机,进程 a 输出第一个字符‘a’表示开始使用打印

机,输出第二个字符‘a’表示结束使用,b 进程操作与 a 进程相同。(由于打印机同一时刻

只能被一个进程使用,所以输出结果不应该出现 abab),如图所示:

sem.h:

sem.c:

执行结果:

        2.例题如图 :
 
共享内存+信号量完成:
 
sem.h:
 
 
sem.c
 

1.c:

2.c:

执行结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值