日期:2014-05-16 浏览次数:20686 次
PV的定义 P就是请求资源,V就是释放资源
P(sv) 如果sv大于0,减小sv。如果sv为0,挂起这个进程的执行。
V(sv) 如果有进程被挂起等待sv,使其恢复执行。如果没有进行被挂起等待sv,增加sv。
P表示通过的意思,V表示释放的意思
System V机制
一.头文件
#include <sys/sem.h>
二.结构体
struct sembuf { unsigned short sem_num; /* semaphore index in array */ //处理的信号量个数 short sem_op; /* semaphore operation */ //要执行的操作类型 short sem_flg; /* operation flags */ //操作标识 };
union semun { int val; struct semid_ds *buf; unsigned short *array; } arg;
三.API函数
1.获取key_t值
key_t ftok(const char *path, int id);
2.获取设置信号量
int semget(key_t key, int nsems, int semflg);
参数:信号量集键值,信号量格式,信号量标志
返回值:成功返回semid,,错误返回-1,
错误号errno:
EACCES 权限过低
EEXIST:id存在,但((semflg &IPC_CREAT) &&(semflg &IPC_EXCL))=0
EINVAL:nsems参数不对
ENOENT:id不存在且semflg &IPC_CREAT=0
ENOSPC:信号量数超过系统限制
当key为IPC_PRIVATE或者当不存在key指定的id时且semflg &IPC_CREAT=0 会创建信号量
3.信号量控制
int semctl(int semid, int semnum, int cmd, ...);
参数:信号量集键值,信号量遍号,命令,可选参数(union semun)
返回值:成功返回整数,是吧返回-1
命令:
GETVAL:返回信号量集中的一个单个的信号量的值
SETVAL:设置信号量集中的一个单独的信号量的值
GETPID:返回最后一个执行semop操作的进程的PID
GETNCNT:用于读取信号量集中的所有信号量的值
GETZCNT:返回这在等待完全空闲的资源的进程数目
GETALL:用于读取信号量集中的所有信号量的值
SETVAL:设置信号量集中的一个单独的信号量的值
IPC_STAT:读取一个信号量集的数据结构semid_ds,并将其存储在semun中的buf参数中
IPC_SET:设置信号量集的数据结构semid_ds中的元素ipc_perm,其值取自semun中的buf参数
IPC_RMID:将信号量集从内存中删除
4.信号量操作
int semop(int semid, struct sembuf *sops, size_t nsops);
参数:信号量集键值,sembuf结构体,操作标志
返回值:成功返回0,失败返回-1
sop->sem_ops的说明:
值为正数,该值会加到现有的信号内含值中。通常用于释放所控资源的使用权;
值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对值。通常用于获取资源的使用权;
值为0,则操作将暂时阻塞,直到信号的值变为0
四.例子
1.
#include <sys/types.h> #include <stdio.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/stat.h> #include <errno.h> #include <unistd.h> #include <stdlib.h> #include <pwd.h> #include <fcntl.h> #include <limits.h> int main(int argc,char **argv) { key_t semkey; int semid, pfd, fv; struct sembuf sbuf; char *lgn; char filename[PATH_MAX+1]; struct stat outstat; struct passwd *pw; /* Get unique key for semaphore. */ if ((semkey = ftok("/tmp", 'b')) == (key_t) -1) { perror("IPC error: ftok"); exit(1); } /* Get semaphore ID associated with this key. */ if ((semid = semget(semkey, 0, 0)) == -1) { /* Semaphore does not exist - Create. */ if ((semid = semget(semkey, 1, IPC_CREAT | IPC_EXCL | S_IRUSR |S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) != -1) { /* Initialize the semaphore. */ sbuf.sem_num = 0; sbuf.sem_op = 2; /* This is the number of runswithout queuing. */ sbuf.sem_flg = 0; if (semop(semid, &sbuf, 1) == -1) { perror("IPC error: semop"); exit(1); } } else if (errno == EEXIST) { if ((semid = semget(semkey, 0, 0)) == -1) { perror("IPC error 1: semget"); exit(1); } } else { perror("IPC error 2: semget"); exit(1); } } }
2.网上找到的例子
#include <sys/types