semctl函数

semctl函数

int semctl(int semid, int semnum, int cmd, …);
@semid:信号量数组标识
@semnum:要操作的信号量数组的信号量下标
@cmd:
IPC_STAT 查询此信号量数组的数据存入arg.buf(buf为struct semid_ds结构体指针)
IPC_RMID 删除指定semid的信号量数组
GETVAL 获取信号量的当前值,
SETVAL 设置信号量的值,初始化要用的命令

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

#if 0


struct semid_ds {
	struct ipc_perm	sem_perm;		/* permissions .. see ipc.h */
	__kernel_time_t	sem_otime;		/* last semop time */
	__kernel_time_t	sem_ctime;		/* last change time */
	struct sem	*sem_base;		/* ptr to first semaphore in array */
	struct sem_queue *sem_pending;		/* pending operations to be processed */
	struct sem_queue **sem_pending_last;	/* last pending operation */
	struct sem_undo	*undo;			/* undo requests on this array */
	unsigned short	sem_nsems;		/* no. of semaphores in array */
};

struct ipc_perm
{
	__kernel_key_t	key;
	__kernel_uid_t	uid;
	__kernel_gid_t	gid;
	__kernel_uid_t	cuid;
	__kernel_gid_t	cgid;
	__kernel_mode_t	mode; 
	unsigned short	seq;
};
	

union semun stat = {0};
struct semid_ds semds = {0};
stat.buf = &semds;
semctl(semid,0,IPC_STAT,stat);

#endif

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 main()
{
	key_t key = ftok(".",97);

	printf("key = %x\n",key);
	int semid = semget(key,1,IPC_CREAT | 0600);
	if(semid < 0)
	{
		perror("semget error");
		return -1;
	}
	
	union semun initval = {0};
	initval.val = 1;
	semctl(semid,0,SETVAL,initval);
	int curval = semctl(semid,0,GETVAL,0);	
	printf("curval = %d\n",curval);

	//p操作
	struct sembuf buf = {0};
	buf.sem_num = 0;
	buf.sem_op = -1;
	semop(semid,&buf,1);

	union semun stat = {0};
	struct semid_ds semds = {0};
	stat.buf = &semds;
	semctl(semid,0,IPC_STAT,stat);
	printf("uid = %d,mode = %o,sem_otime = %ld,sem_nsems = %ld\n",semds.sem_perm.uid,semds.sem_perm.mode,semds.sem_otime,semds.sem_nsems);
	printf("getuid() = %d,time() = %ld\n",getuid(),time(NULL));

	semctl(semid,0,IPC_RMID,0);	//删除信号量
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
semctl函数是Linux系统中用于对信号量进行控制操作的系统调用函数函数原型: ```c #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semctl(int semid, int semnum, int cmd, ...); ``` 参数说明: - `semid`:信号量集标识符; - `semnum`:信号量的编号,从0开始; - `cmd`:控制命令,可以是IPC_RMID(删除信号量集)、IPC_SET(设置信号量集的IPC权限)、IPC_STAT(获取信号量集的状态信息)、GETVAL(获取信号量的值)、SETVAL(设置信号量的值)、GETPID(获取上次执行semop操作的进程ID)、GETNCNT(获取等待该信号量变为非0的进程数)、GETZCNT(获取等待该信号量变为0的进程数); 如果cmd为IPC_SET,则需要传递一个union semun类型的参数。semun结构定义如下: ```c union semun { int val; /* SETVAL命令使用的信号量值 */ struct semid_ds *buf; /* IPC_STAT和IPC_SET命令使用的结构体指针 */ ushort *array; /* GETALL和SETALL命令使用的数组指针 */ }; ``` 函数返回值为执行结果,通常为0表示执行成功,否则表示执行失败。 常用的控制命令如下: - `IPC_RMID`:删除信号量集; - `IPC_SET`:设置信号量集的IPC权限; - `IPC_STAT`:获取信号量集的状态信息; - `GETVAL`:获取信号量的值; - `SETVAL`:设置信号量的值。 需要注意的是,当使用IPC_RMID命令删除一个信号量集时,如果有其他进程正在使用该信号量集,那么这些进程将会收到一个SIGINT信号,即如同按下了Ctrl+C键一样。因此,在删除信号量集之前,需要确保没有其他进程正在使用该信号量集。 另外,当使用SETVAL命令设置信号量的值时,需要将union semun类型的参数中的`val`字段设置为要设置的值。而当使用GETVAL命令获取信号量的值时,需要将union semun类型的参数中的`buf`字段设置为一个`semid_ds`结构体指针,用于存放获取的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值