共享内存和信号量
1) 获取信号量标识符 int semget(key_t key, int nsems, int flag)
2) 操作信号量(初始化,删除等) int semctl(int semid, int semnum, int cmd, /*union semun*/)
3) 对信号量进行增减操作,在该操作是一个原子操作 int semop(int semid, struct sembuf semoparray[ ], size_t nops)
sem.h
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FTOK_FILE "/etc/profile"
#define TEST_FILE "/home/root/sem_file.dat"
#define STR_LEN 32
#define SHM_SIZE 256
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
};
typedef struct _tag_shm
{
char buf[SHM_SIZE];
unsigned short num;
}shm_t;
int creat_sem(void)
{
int semid = 0;
key_t key = ftok(FTOK_FILE,11);
if(key == -1)
{
printf("%s: key =-1!\n",__func__);
return -1;
}
semid = semget(key,1,IPC_CREAT|0666);
if(semid == -1)
{
printf("%s: semid =-1!\n",__func__);
return -1;
}
return semid;
}
int set_semvalue(int semid)
{
union semun sem_arg;
sem_arg.val = 1;
if(semctl(semid,0,SETVAL,sem_arg) == -1)
{
printf("%s: can't set value for sem!\n",__func__);
return -1;
}
return 0;
}
int sem_p(int semid)
{
struct sembuf sem_arg;
sem_arg.sem_num = 0;
sem_arg.sem_op = -1;
sem_arg.sem_flg = SEM_UNDO;
if(semop(semid, &sem_arg,1) == -1)
{
printf("%s: can't do the sem_p!\n",__func__);
return -1;
}
return 0;
}
int sem_v(int semid)
{
struct sembuf sem_arg;
sem_arg.sem_num = 0;
sem_arg.sem_op = 1;
sem_arg.sem_flg = SEM_UNDO;
if(semop(semid, &sem_arg,1) == -1)
{
printf("%s: can't do the sem_v!\n",__func__);
return -1;
}
return 0;
}
int del_sem(int semid)
{
if(semctl(semid,0,IPC_RMID) == -1)
{
printf("%s : can't rm the sem!\n",__func__);
return -1;
}
return 0;
}
read
#include "sem.h"
int main(void)
{
int semid,shmid;
char buf[STR_LEN] = {0};
int i = 0;
void * pshm_addr = NULL;
shm_t *pshm = NULL;
/*获取信号量标识符*/
semid = creat_sem( );
if(semid == -1)
{
printf("%s : semid = %d!\n", __func__, semid);
return -1;
}
/*创建信号量之后的,初始化操作*/
if(set_semvalue(semid))
{
printf("%s : set_semvalue failed!\n",__func__);
return -1;
}
/*获取共享内存标识符*/
shmid = shmget(ftok(FTOK_FILE, 111), sizeof(shm_t), IPC_CREAT|0666);
if(shmid == -1)
{
printf("%s : shmid = %d!\n",__func__, shmid);
return -1;
}
/*当前进程连接该共享内存段*/
pshm_addr = shmat(shmid, 0 , 0);
if(pshm_addr == (void *)-1)
{
printf("%s : pshm_addr == (void*)0!\n",__func__);
return -1;
}
pshm = (shm_t*)pshm_addr;
printf("read process semid is %d,shmid is %d!\n", semid,shmid);
/*让写数据的进程先运行*/
sleep(4);
for(; ;)
{
/*占用信号量,p操作*/
if(sem_p(semid))
{
printf("%s : sem_p failed !\n",__func__);
return -1;
}
printf("enter read process!\n");
printf("pshm->num is %d!\n",pshm->num);
printf("pshm->buf is %s", pshm->buf);
printf("leave read process!\n\n");
/*释放信号量,v操作*/
if(sem_v(semid))
{
printf("%s : sem_v failed!\n",__func__);
return -1;
}
if(!strncmp(pshm->buf, "end", 3))
break;
sleep(2);
}
/*删除信号量*/
if(del_sem(semid))
{
printf("%s : del_sem failed!\n", __func__);
return -1;
}
/*进程和共享内存脱离*/
if(shmdt(pshm_addr) == -1)
{
printf("%s : shmdt failed!\n",__func__);
return -1;
}
/*删除共享内存*/
if(shmctl(shmid, IPC_RMID, 0) == -1)
{
printf("%s : shmctl failed!\n",__func__);
return -1;
}
printf("BYE!\n");
return 0;
}
write
#include "sem.h"
int main(void)
{
int semid, shmid;
char buf[STR_LEN] = {0};
void *pshm_addr = NULL;
shm_t * pshm = NULL;
int i = 0;
/*获取信号量标识符*/
semid = creat_sem( );
if(semid == -1)
{
printf("%s : semid = %d!\n", __func__, semid);
return -1;
}
/*获取共享内存标识符*/
shmid = shmget(ftok(FTOK_FILE,111), sizeof(shm_t), IPC_CREAT|0666);
if(shmid == -1)
{
printf("%s: shmid = %d!\n", __func__, shmid);
return -1;
}
/*当前进程连接该共享内存段*/
pshm_addr = shmat(shmid, 0, 0);
if(pshm_addr == (void *)-1)
{
printf("%s : pshm_addr = (void*)-1!\n",__func__);
return -1;
}
pshm = (shm_t*)pshm_addr;
printf("read process : semid is %d, shmid is %d!\n",semid, shmid);
for(; ;)
{
/*占用信号量,p操作*/
if(sem_p(semid))
{
printf("%s : sem_p failed !\n",__func__);
return -1;
}
printf("enter write process!\n");
printf("enter something, end with end >\n");
fgets(buf, STR_LEN, stdin);
pshm->num = i++;
strcpy(pshm->buf, buf);
printf("leave write process!\n\n");
/*释放信号量,v操作*/
if(sem_v(semid))
{
printf("%s : sem_v failed!\n",__func__);
return -1;
}
if(!strncmp(pshm->buf , "end", 3))
break;
}
/*进程和共享内存脱离*/
if(shmdt(pshm_addr) == -1)
{
printf("%s : shmdt is failed!\n",__func__);
return -1;
}
printf(" Good Bye! \n");
return 0;
}
本博客内容均来自网络,如有雷同,是我抄袭!
浙公网安备 33010602011771号