semget 函数为获取信号量函数
使用格式:
#include
int semget(key_t _key ,int _nsems,int _semflg);
功能:创建一个新的信号量或获取一个已经存在的信号量的键值。
返回值:成功返回信号量的标识码ID。失败返回-1;
参数:
_key为整型值,用户可以自己设定。有两种情况:
1. 键值是IPC_PRIVATE,该值通常为0,意思就是创建一个仅能被进程进程给我的信号量。
2. 键值不是IPC_PRIVATE,我们可以指定键值,例如1234;也可以一个ftok()函数来取得一个唯一的键值。
_nsems表示初始化信号量的个数。比如我们要创建一个信号量,则该值为1.,创建2个就是2。
_semflg:信号量的创建方式或权限。有IPC_CREAT,IPC_EXCL。
IPC_CREAT如果信号量不存在,则创建一个信号量,否则获取。
IPC_EXCL只有信号量不存在的时候,新的信号量才建立,否则就产生错误。
ipcs –s用来查看信号量。
如果需要从新建立键值是一样的信号量需要删除之前的信号量,新建的信号量才能起效。
semctl()控制信号量的函数
格式:
#include
int semctl(int _semid ,int _semnum,int
_cmd ……);
功能:控制信号量的信息。
返回值:成功返回0,失败返回-1;
参数:
_semid信号量的标志码(ID),也就是semget()函数的返回值;
_semnum,操作信号在信号集中的编号。从0开始。
_cmd命令,表示要进行的操作。
下面列出的这些命令来源于百度!
参数cmd中可以使用的命令如下:
IPC_STAT读取一个信号量集的数据结构semid_ds,并将其存储在semun中的buf参数中。
IPC_SET设置信号量集的数据结构semid_ds中的元素ipc_perm,其值取自semun中的buf参数。
IPC_RMID将信号量集从内存中删除。
GETALL用于读取信号量集中的所有信号量的值。
GETNCNT返回正在等待资源的进程数目。
GETPID返回最后一个执行semop操作的进程的PID。
GETVAL返回信号量集中的一个单个的信号量的值。
GETZCNT返回这在等待完全空闲的资源的进程数目。
SETALL设置信号量集中的所有的信号量的值。
SETVAL设置信号量集中的一个单独的信号量的值。
semop();信号来那个操作处理的函数
格式:#include
int semop(int semid
,struct sembuf *_sops
,size_t _nsops);
功能:用户改变信号量的值。也就是使用资源还是释放资源使用权。
返回值:成功返回0,失败返回-1;
参数:
_semid :信号量的标识码。也就是semget()的返回值。
_sops是一个指向结构体数组的指针。
struct sembuf{
unsigned short sem_num;//第几个信号量,第一个信号量为0;
short sem_op;//对该信号量的操作。
short _semflg;
};
sem_num:操作信号在信号集中的编号。第一个信号的编号为0;
sem_op
:如果其值为正数,该值会加到现有的信号内含值中。通常用于释放所控资源的使用权;如果sem_op的值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对值。通常用于获取资源的使用权;如果sem_op的值为0,则操作将暂时阻塞,直到信号的值变为0。
_semflgIPC_NOWAIT
//对信号的操作不能满足时,semop()不会阻塞,并立即返回,同时设定错误信息。
IPC_UNDO
//程序结束时(不论正常或不正常),保证信号值会被重设为semop()调用前的值。这样做的目的在于避免程序在异常情况下结束时未将锁定的资源解锁,造成该资源永远锁定。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
};
union semun sem_union;
struct sembuf sem_buf;
key_t key = 0;
int sem_id = 0;
unsigned short arry[2] = {0,2};
int main()
{
sem_union.array=arry;
key =
ftok("./123",1); //获取键值
//创建信号量
//int semget(key_t _key ,int _nsems,int _semflg);
//key_t sem键值 _nsems 创建信号量个数 _semflg 创建属性
sem_id = semget(key, 2, 0666 | IPC_CREAT);
printf("sem_id =
%d\n",sem_id); //打印semID
if (semctl(sem_id,1,SETALL,sem_union)==-1)
{
perror("Sem init");
exit(1);
}
sem_buf.sem_num=1;
sem_buf.sem_op=-1;
sem_buf.sem_flg=SEM_UNDO;
if (semop(sem_id,&sem_buf,1)==-1)
{
perror("Sem P
operation");
exit(1);
}
printf("step 1\n");
sem_buf.sem_num=1;
sem_buf.sem_op=-1;
sem_buf.sem_flg=SEM_UNDO;
if (semop(sem_id,&sem_buf,1)==-1)
{
perror("Sem P
operation");
exit(1);
}
printf("END\n");
return 0;
}