大于或等于0时代表可供并发进程使用的资源实体数;
小于0时代表正在等待使用临界区的进程数;
用于互斥的信号量初始值应大于0;
只能通过P、V原语操作而改变;
信号量元素组成:
1、表示信号量元素的值;
2、最后操作信号量元素的进程ID
3、等待信号量元素值+1的进程数;
4、等待信号量元素值为0的进程数;
二、主要函数
1.1 创建信号量
int semget(
key_t key, //标识信号量的关键字,有三种方法:1、使用IPC——PRIVATE让系统产生,
// 2、挑选一个随机数,3、使用ftok从文件路径名中产生
int nSemes, //信号量集中元素个数
int flag //IPC_CREAT;IPC_EXCL 只有在信号量集不存在时创建
)
成功:返回信号量句柄
失败:返回-1
1.2 使用ftok函数根据文件路径名产生一个关键字
key_t ftok(const char *pathname,int proj_id)
路径名称必须有相应权限
1.3 控制信号量
int semctl(
int semid, //信号量集的句柄
int semnum, //信号量集的元素数
int cmd, //命令
/*union senum arg */... //
)
成功:返回相应的值
失败:返回-1
命令详细说明:
cmd: IPC_RMID 删除一个信号量
IPC_EXCL 只有在信号量集不存在时创建
IPC_SET 设置信号量的许可权
SETVAL 设置指定信号量的元素的值为 agc.val
GETVAL 获得一个指定信号量的值
GETPID 获得最后操纵此元素的最后进程ID
GETNCNT 获得等待元素变为1的进程数
GETZCNT 获得等待元素变为0的进程数
union senum 定义如下:
union senum{
int val
struct semid_ds *buf
unsigned short * array
}agc
其中 semid_ds 定义如下:
struct semid_ds{
struct ipc_pem sem_pem //operation pemission struct
time_t sem_otime //last semop()time
time_t sem_ctime //last time changed by semctl()
struct sem *sembase //ptr to first semaphore in array
struct sem_queue *sem_pending//pending operations
struct sem_queue *sem_pending_last//last pending operations
struct sem_undo *undo //undo requests on this arrary
unsigned short int sem_nsems//number of semaphores in set
}
1.4 对信号量 +1 或 -1 或测试是否为0
int semop(
int semid,
struct sembuf *sops, //指向元素操作数组
unsigned short nsops //数组中元素操作的个数
)
结构 sembuf 定义
sembuf{
short int sem_num//semaphore number
short int sem_op//semaphore operaion
short int sem_flg //operation flag
}
三、例子:
2.1 服务器
#include <sys/sem.h>
#include <sys/ipc.h>
#define SEGSIZE 1024
#define READTIME 1
union semun {
int val
struct semid_ds *buf
unsigned short *array
} arg
//生成信号量
int sem_creat(key_t key)
{
union semun sem
int semid
sem.val = 0
semid = semget(key,1,IPC_CREAT|0666)
if (-1 == semid){
printf("create semaphore error\n")
exit(-1)
}
semctl(semid,0,SETVAL,sem)
return semid
}
//删除信号量
void del_sem(int semid)
{
union semun sem
sem.val = 0
semctl(semid,0,IPC_RMID,sem)
}
//p
int p(int semid)
{
struct sembuf sops={0,+1,IPC_NOWAIT}
return (semop(semid,&sops,1))
}
//v
int v(int semid)
{
struct sembuf sops={0,-1,IPC_NOWAIT}
return (semop(semid,&sops,1))
}
int main()
{
key_t key
int shmid,semid
char *shm
char msg[7] = "-data-"
char i
struct semid_ds buf
key = ftok("/",0)
shmid = shmget(key,SEGSIZE,IPC_CREAT|0604)
if (-1 == shmid){
printf(" create shared memory error\n")
return -1
}
shm = (char *)shmat(shmid,0,0)
if (-1 == (int)shm){
printf(" attach shared memory error\n")
return -1
}
semid = sem_creat(key)
for (i = 0i <= 3i++){
sleep(1)
p(semid)
sleep(READTIME)
msg[5] = '0' + i
memcpy(shm,msg,sizeof(msg))
sleep(58)
v(semid)
}
shmdt(shm)
shmctl(shmid,IPC_RMID,&buf)
del_sem(semid)
return 0
//gcc -o shm shm.c -g
}
2.2 客户端
#include <sys/sem.h>
#include <time.h>
#include <sys/ipc.h>
#define SEGSIZE 1024
#define READTIME 1
union semun {
int val
struct semid_ds *buf
unsigned short *array
} arg
// 打印程序执行时间
void out_time(void)
{
static long start = 0
time_t tm
if (0 == start){
tm = time(NULL)
start = (long)tm
printf(" now start ...\n")
}
printf(" second: %ld \n",(long)(time(NULL)) - start)
}
//创建信号量
int new_sem(key_t key)
{
union semun sem
int semid
sem.val = 0
semid = semget(key,0,0)
if (-1 == semid){
printf("create semaphore error\n")
exit(-1)
}
return semid
}
//等待信号量变成0
void wait_v(int semid)
{
struct sembuf sops={0,0,0}
semop(semid,&sops,1)
}
int main(void)
{
key_t key
int shmid,semid
char *shm
char msg[100]
char i
key = ftok("/",0)
shmid = shmget(key,SEGSIZE,0)
if(-1 == shmid){
printf(" create shared memory error\n")
return -1
}
shm = (char *)shmat(shmid,0,0)
if (-1 == (int)shm){
printf(" attach shared memory error\n")
return -1
}
semid = new_sem(key)
for (i = 0i <3i ++){
sleep(2)
wait_v(semid)
printf("Message geted is: %s \n",shm + 1)
out_time()
}
shmdt(shm)
return 0
// gcc -o shmc shmC.c -g
}
mien phi tai phim dit nhau的意思:全部释义和例句>>风采披大屏DIT来说。
短语
Personnel mien 员工风采 首页
mien mien 风采
Staff Mien 员工风采
artistic mien 艺术风采
Kim Mien 兼勉族
mien mian 些函两
Li Mien 李勉
Mien Tay 一为棉泰 则请到棉泰 胡志明市的棉泰
TA MIEN 大面
semget() 可以使用系统调用semget()创建一个新的信号量集,或者存取一个已经存在的信号量集:系统调用:semget()
原型:intsemget(key_t key,int nsems,int semflg)
返回值:如果成功,则返回信号量集的IPC标识符。如果失败,则返回-1:errno=EACCESS(没有权限)
EEXIST(信号量集已经存在,无法创建)
EIDRM(信号量集已经删除)
ENOENT(信号量集不存在,同时没有使用IPC_CREAT)
ENOMEM(没有足够的内存创建新的信号量集)
ENOSPC(超出限制)
系统调用semget()的第一个参数是关键字值(一般是由系统调用ftok()返回的)。系统内核将此值和系统中存在的其他的信号量集的关键字值进行比 较。打开和存取操作与参数semflg中的内容相关。IPC_CREAT如果信号量集在系统内核中不存在,则创建信号量集。IPC_EXCL当和 IPC_CREAT一同使用时,如果信号量集已经存在,则调用失败。如果单独使用IPC_CREAT,则semget()要么返回新创建的信号量集的标识 符,要么返回系统中已经存在的同样的关键字值的信号量的标识符。如果IPC_EXCL和IPC_CREAT一同使用,则要么返回新创建的信号量集的标识 符,要么返回-1。IPC_EXCL单独使用没有意义。参数nsems指出了一个新的信号量集中应该创建的信号量的个数。信号量集中最多的信号量的个数是 在linux/sem.h中定义的:
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)