📄 outshm.c
字号:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "err_exit.h"
struct exchange {
char buf[BUFSIZ+80]; /* 需交换的数据*/
int seq; /* 客户填入的顺序号 */
};
int open_semaphore_set( key_t, int);
void init_a_semaphore( int, int, int);
int semaphore_P(int);
int semaphore_V(int);
/* 创建/打开共享存储段,连接它到用户地址空间,返回它在用户空间的地址 */
unsigned char *shminit(key_t key)
{
int shmid;
unsigned char *retval;
if((shmid = shmget(key,sizeof(struct exchange),0666|IPC_CREAT))== -1)
err_exit("shmget");
if((retval = shmat(shmid,(unsigned char *)0,0)) == (unsigned char *)-1 )
err_exit("shmmat");
return retval;
}
/* P操作--企图进入一关键区 */
int semaphore_P(int sem_id)
{
struct sembuf sb;
sb.sem_num = 0;
sb.sem_op = -1; /* P操作-信号量值减少 */
sb.sem_flg = SEM_UNDO; /* 如果死亡,解除信号量请求*/
if (semop(sem_id, &sb, 1) == -1){
fprintf(stderr,"semaphore_P failed\n");
return(0);
}
return(1);
}
/* V操作--离开关键区 */
int semaphore_V(int sem_id)
{
struct sembuf sb;
sb.sem_num = 0;
sb.sem_op = 1; /* V操作-信号量值增加 */
sb.sem_flg = SEM_UNDO; /* 如果死亡,解除信号量请求*/
if (semop(sem_id, &sb, 1) == -1){
fprintf(stderr,"semaphore_V failed\n");
return(0);
}
return(1);
}
/* 说明semun结构 */
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
/* 获得指定的信号量之值 */
int get_sem_val( int sid, int semnum )
{
return( semctl(sid, semnum, GETVAL, 0));
}
/* 给指定的信号量赋初值 */
void init_a_semaphore( int sid, int semnum, int initval)
{
union semun semopts;
semopts.val = initval;
semctl( sid, semnum, SETVAL, semopts);
}
/* 给指定的信号量集合赋初值 */
void init_all_semaphore( int sid, int val_array[])
{
union semun semopts;
semopts.array = val_array;
semctl( sid, 0, SETALL, semopts);
}
/* 改变信号量集合的访问权限,权限参数必须是形如"660"的字符串 */
int changemode(int sid, char *mode)
{
int rc;
union semun semopts;
struct semid_ds mysemds;
/* 注意,应先使semopts.buf 指向我们自己定义的缓冲区! */
semopts.buf = &mysemds;
/* 获得内部数据结构的当前值 */
if ((rc = semctl(sid, 0, IPC_STAT, semopts)) == -1)
return -1;
/* 改变访问权限 */
sscanf(mode, "%o", &semopts.buf->sem_perm.mode);
/* 更新内部数据结构 */
return(semctl(sid, 0, IPC_SET, semopts));
}
/* 删除指定的信号量集合 */
int rm_semaphore(int sid)
{
return(semctl(sid, 0, IPC_RMID,0));
}
int open_semaphore_set( key_t keyval, int numsems )
{
int sid;
if (!numsems)
return(-1);
if((sid = semget( keyval, numsems, IPC_CREAT | 0660 )) == -1)
return(-1);
else
return(sid);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -