Linux中的信号量
目次信号量概念
界说
操作
范例
应用
信号量封装
一、创建信号量
头文件
函数原型
参数说明
返回值
示例
二、设置信号量初始值
头文件
函数原型
参数解释
返回值
示例
三、信号量的P操作
头文件
函数原型
参数解释
返回值
示例
四、信号量的V操作
示例
信号量概念
界说
信号量是一种用于多历程 / 线程同步的整数变量,用于控制对共享资源的访问。凡是遇到内存操作就可以实现加锁。
操作
P 操作:信号量值减 1,若值小于 0 则历程壅闭,否则继承实验。
V 操作:信号量值加 1,如有历程壅闭则叫醒一个。
范例
二进制信号量:值为 0 或 1,用于互斥访问。
计数信号量:值为非负整数,控制多资源访问。
应用
互斥访问:确保同一时间只有一个历程 / 线程访问共享资源。
资源管理:控制对多个雷同资源的并发访问。
历程同步:包管历程或线程按顺序实验。
信号量封装
1、创建/获取信号量
2、设置初始值,一样平常为1
3、P操作
4、V操作
一、创建信号量
semctl 是一个在 Unix 和类 Unix 系统中用于控制信号量集的系统调用函数。
头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h> 函数原型
int semget(key_t key, int nsems, int semflg); 参数说明
key:唯一标识。
nsems:要创建的信号量会合信号量的数量。
semflg:标志位,用于指定创建信号量集的权限和其他选项。它可以是以下值的组合:
IPC_CREAT:如果信号量集不存在,则创建它。
IPC_EXCL:与 IPC_CREAT 一起使用,如果信号量集已经存在,则返回错误。
权限标志(如 0666):指定信号量集的访问权限。
返回值
成功时,返回一个非负整数,即信号量集的标识符(semaphore identifier),后续的信号量操作将使用这个标识符。
失败时,返回 -1,并设置 errno 以指示错误范例。
示例
int sem_create(key_t key, int num_sems)
{
int res = 0;
res = semget(key, num_sems, IPC_CREAT | 0666);
if (res < 0)
{
perror("semget error");
}
return res;
} 二、设置信号量初始值
semctl 是类 Unix 系统中用于控制信号量集的一个系统调用,借助它可以或许对信号量集进行多种操作,比方设置信号量的值、获取信号量的值、删除信号量集等。
头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h> 函数原型
int semctl(int semid, int semindex, int cmd, ...);
参数解释
semid:信号量集的标识符,由 semget 函数返回,用于指定要操作的信号量集。
semindex:为第几个信号量设置值。
cmd:要实验的命令,常见的命令如下:
SETVAL:把单个信号量的值设置为传入的参数值。
GETVAL:获取单个信号量的值。
SETALL:设置信号量会合全部信号量的值。
GETALL:获取信号量会合全部信号量的值。
IPC_RMID:删除信号量集。
...:这是可选参数,依据 cmd 的不同而有所不同。在使用 SETVAL 或 SETALL 时,需要传入对应的参数值。通常使用 union semun 范例的变量来传递该参数,union semun 的界说如下:
union semun
{
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short*array;/* Array for GETALL, SETALL */
struct seminfo*__buf;/* Buffer for IPC_INFO
(Linux-specific) */
};
返回值
成功时,依据 cmd 的不同返回不同的值。比方,GETVAL 命令返回信号量的值,IPC_RMID 命令成功时返回 0。
失败时,返回 -1,并设置 errno 以指示错误范例。
示例
union semun
{
int val; /* Value for SETVAL */
struct semid_ds* buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short* array;/* Array for GETALL, SETALL */
struct seminfo* __buf;/* Buffer for IPC_INFO
(Linux-specific) */
};
int sem_setval(int semid, int semindex, int val)
{
union semun arg;
arg.val = val;
int res = semctl(semid, semindex, SETVAL, arg);
if (res < 0)
{
perror("semctl error");
}
return res;
} 三、信号量的P操作
semop 是类 Unix 系统中用于对信号量集进行操作的系统调用,它答应历程原子性地对一个或多个信号量进行改变,常用于实现历程间的同步和互斥。
头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h> 函数原型
int semop(int semid, struct sembuf *sops, size_t nsops);
参数解释
semid:信号量集的标识符,由 semget 函数返回,用于指定要操作的信号量集。
sops:一个指向 struct sembuf 范例数组的指针,struct sembuf 结构体界说了对信号量的详细操作,其结构如下:
struct sembuf
{
unsigned short sem_num;// 信号量集中信号量的编号,从 0 开始
short sem_op; // 对信号量的操作值
short sem_flg;// 操作标志
};
sem_num:指定要操作的信号量在信号量会合的编号。
sem_op:表现对信号量的操作值,有以下几种情况:
若 sem_op 为正数,则表现释放相应数量的资源,信号量的值会增长 sem_op。
若 sem_op 为负数,则表现请求相应数量的资源,信号量的值会减少 sem_op。若信号量当前值小于 |sem_op|,则历程可能会壅闭,详细取决于 sem_flg。
若 sem_op 为 0,则表现等待信号量的值变为 0。
sem_flg:操作标志,常用的标志有:
IPC_NOWAIT:若操作不能立刻实验,则不壅闭,直接返回错误。
SEM_UNDO:当历程停止时,系统会自动撤销该历程对信号量的操作。
nsops:sops 数组中元素的个数,即要实验的操作数量。
返回值
成功时,返回 0。
失败时,返回 -1,并设置 errno 以指示错误范例。
示例
// 3、信号量的P操作
int sem_p(int semid, int semindex)
{
int res = 0;
struct sembuf buf = { semindex,-1,SEM_UNDO };
res = semop(semid, &buf, 1);
if (res < 0)
{
perror("sem_p error");
}
return res;
} 四、信号量的V操作
v操作唯一的变化就是从-1变成+1
示例
// 4、信号量的V操作
int sem_v(int semid, int semindex)
{
int res = 0;
struct sembuf buf = { semindex,1,SEM_UNDO };
res = semop(semid, &buf, 1);
if (res < 0)
{
perror("sem_p error");
}
return res;
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]