信号量基本操作

本文详细介绍了Linux信号量的概念,包括其作用、PV操作、相关API函数如semget、semctl、semop的使用,并提供了如何利用信号量实现多进程交替报数的示例。通过对信号量值的增减,实现进程间的同步与资源互斥访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概述

        信号量(变量可以有值)是一种实现任务间通信的机制,可以实现任务之间同步或临界资源的互斥访问(类似与互斥锁),常用于协助一组相互竞争的任务来访问临界资源。
        信号量用来描述一组资源可使用次数(可以使用的次数),
                值>0--有资源可用,可以访问临界资源(公共资源),
                值==0--当前没有资源可用,所以会阻塞等待
        信号量值(变量的值)的改变是通过函数来实现的加减,(当信号量的值为0的时候,再来申请就会阻塞)阻塞原因是函数。
        信号量是一个非负整数,所有获取它的任务都会将该信号量值减1(通过函数实现,减少的值可以设置),当该信号量的值为0时,所有试图获取它的任务都将处于阻塞状态。通常一个信号量的计数值用于对应有效的资源数(一般减少的值都是1),表示剩下的可被占用的互斥资源数。
        补充:当把信号量的值设定为1的时候,这个时候相当于二值信号量。

二、PV操作

        访问临界资源的所有进程在访问临界资源前进行P(PASS)操作(信号量值-1),访问完之后,再将进行V操作(信号该信号量,使得信号量的信号量值+1)。如果没有申请到信号量就会被挂起(阻塞)。
信号量通过PV操作实现同步:
        PV操作是基于对信号量值进行的操作,当信号量值等于0,此进程再使用该信号量的时候会进入阻塞(进行减操作),当信号量的值大于0时候,此进程使用该信号量才会继续执行。
        信号量>0,进程可以申请共享资源。
        信号量=0,进程申请资源会被挂起。
简单来说P操作有两种情况:
        (1)在P操作前,如果所使用的信号量对应信号量值大于0,则进行P操作时,该信号量的值减1
        (2)在P操作前,如果所使用的信号量对应的信号量值等于0,则进行P操作时,该进程置会进入阻塞状态,直到当前信号量的值大于0即有资源可用了。
        如果在该信号量有进程在等待可用资源,则唤醒一个阻塞进程;如果没有进程等待它,则释放一个资源(即信号量值加1)

        V操作就是释放信号量,对应信号量的值进行加法操作。

补充概念:
        数组:同一类变量的集合(inta[10])信号量集:信号量的集合(信号量数组)
        变量:数组里面元素,有自己的值信号量:信号量集里面的元素,也有自己的值例如:{10,20}
        数组里面的变量通过数组+下标找到自己信号量通过信号量集和下标找到自己
        变量的值:就是变量的值信号量值:也是一个数值--信号量的值对应的也是一个整数

使用的头文件:
        #include<stdio.h>
        #include<sys/types.h>
        #include<sys/ipc.h>
        #include<string.h>
        #include<sys/sem.h>
        #include<unistd.h>
        #include<stdlib.h>
        #include<sys/wait.h>

三、相关API函数

1.semget()

头文件:
        #include<sys/types.h>
        #include<sys/ipc.h>
        #include<sys/sem.h>
函数原型:

        int semget(key_t key,int nsems,int semflg);
函数功能:

        创建并打开信号量集,信号量的值默认值为0
函数参数:
        key_t key:信号量的键值可通过ftok生成一个键值,也可以使用现有的信号量键值
        int nsems:创建信号量集中的信号量数目--信号量集合,信号量的个数值,如果引用一个现存的信号量集合,则将nsems指定为0。--也可以为当信号量集里面信号量的数量
        int semflg:读写权限和打开模式(通过位运算符进行拼接)
        IPC_CREAT----用于创建信号量,如果通过键值生成的信号量存在就直接使用,如果没有该信号量就创建。
        IPC_EXCL---与IPC_CREAT|IPC_EXCL用于检测信号量集是否存在
返回值:
        成功:信号量集ID
        失败:-1
注意:
        第二个参数如果已经创建信号量集,这个参数要给0,也可以给小于或者等于需要打开的这个信号量集的信号量个数。

#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<stdio.h>

int main(int argc,char* argv[])
{
	key_t key;
	int semid;
	//调用ftok函数
	key = ftok(argv[1],1);
	
	//调用semget函数
	semid = semget(key,6,IPC_CREAT|IPC_EXCL);
	
	printf("semget success semid = %d\r\n",semid);
	
	return 0;
}

2.semctl()

头文件:

        #include <sys/types.h>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值