信号量_实现共享内存
1.sem.h
#ifndef __SEM_H__ #define __SEM_H__ #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/shm.h> #include <string.h> #include <strings.h> #include <unistd.h> union semun{ int val; /* Value for SETVAL */ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* Array for GETALL, SETALL */ struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */ }; key_t Get_Key(void); int Shm_Creat(key_t key, size_t size); void *Shm_At(int shmid); int Shm_Dt(const void *shmaddr); int Shm_Del(int shmid); int Sem_Creat(key_t key); void Sem_Init(int semid, int value); void Sem_P(int semid); void Sem_V(int semid); int Sem_Delet(int semid); #endif
2.shm.c
#include"sem.h" //创建获取 int Shm_Creat(key_t key, size_t size) { int shmid =shmget(key, size, 0666|IPC_CREAT); if(shmid < 0){ perror("Shm_Creat shmget failed "); exit(1); } return shmid; } //挂载 void *Shm_At(int shmid) { char *shmat_rel =shmat(shmid,NULL,0); if(shmat_rel < 0){ perror("Shm_At shmat failed "); exit(1); } return shmat_rel; } //卸载 int Shm_Dt(const void *shmaddr) { int shmdt_rel =shmdt(shmaddr); if(shmdt_rel < 0){ perror("Shm_Dt shmdt failed "); exit(1); } return shmdt_rel; } //删除 int Shm_Del(int shmid) { int shmctl_rel =shmctl(shmid, IPC_RMID, NULL); if(shmctl_rel < 0){ perror("Shm_Del shmctl failed "); exit(1); } return shmctl_rel; }
3.sem.c
#include "sem.h" //获取key key_t Get_Key(void) { key_t key =ftok("/",0x66); if(key <0){ perror("Get_Key ftok failed"); exit(1); } return key; } //创建获取 int Sem_Creat(key_t key) { int sem_num =1; int semid = semget(key, sem_num,IPC_CREAT|0666); if(semid<0){ perror("sem_creat semget failed"); exit(1); } return semid; } //初始化 void Sem_Init(int semid, int value) { union semun sem; sem.val = value; if( semctl(semid,0,SETVAL,sem) <0 ){ perror("sem_init semctl init failed"); exit(1); } } //P操作 void Sem_P(int semid) { struct sembuf buf ={0,-1,SEM_UNDO}; if( semop(semid,&buf,1) <0 ){ perror("sem_p semop failed"); exit(1); } } //V操作 void Sem_V(int semid) { struct sembuf buf ={0,1,SEM_UNDO}; if( semop(semid,&buf,1) <0 ){ perror("sem_v semop failed"); exit(1); } } //删除 int Sem_Delet(int semid) { union semun sem; if( semctl(semid,0,IPC_RMID, sem) <0 ){ perror("sem_delet semctl failed"); exit(1); } }
3.sem_c.c
#include "sem.h" int main(void) { //sem key_t key =Get_Key(); int semid =Sem_Creat(key); Sem_Init(semid,0); //shm int shmid =Shm_Creat(key,1024); char *shmat_add =Shm_At(shmid); while(1){ //to write P操作 Sem_V(semid); fgets(shmat_add, 1024, stdin); if(strncmp(shmat_add, "quit", 4) ==0) break; } Shm_Dt(shmat_add); Shm_Del(shmid); Sem_Delet(semid); return 0; }
4.sem_s.c
#include "sem.h" int main(void) { //sem key_t key =Get_Key(); int semid =Sem_Creat(key); Sem_Init(semid,0); //shm int shmid =Shm_Creat(key,1024); char *shmat_add =Shm_At(shmid); while(1){ //to read V操作 Sem_P(semid); fputs(shmat_add, stdout); if(strncmp(shmat_add, "quit", 4) ==0) break; } Shm_Dt(shmat_add); Shm_Del(shmid); Sem_Delet(semid); return 0; }
测试:
success !
<笔记>
1.注意头文件是否遗漏 !!
2.信号量初始化了一次
3.