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); //删除信号量
}