关于对消息队列,共享内存,信号量的具体介绍
https://blog.csdn.net/qq_46777053/article/details/108804717
mySemSercer.c
#include<stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/shm.h>
#include<stdlib.h>
#include <sys/sem.h>
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext; /* message data */
};
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) */
};
void pGet(int sem_id){
struct sembuf sops;
sops.sem_num = 0;
sops.sem_op =-1;
sops.sem_flg = SEM_UNDO;
if(semop(sem_id,&sops,1) == -1){
printf("pGet failed!!\n");
exit(-1);
}
}
void vPut(int sem_id){
struct sembuf sops;
sops.sem_num = 0;
sops.sem_op = 1;
sops.sem_flg = SEM_UNDO;
if(semop(sem_id,&sops,1) ==-1){
printf("vPut failed!!\n");
exit(-1);
}
}
//目的: 通过消息队列来实现进程间的通讯,在进程到消息来访问共享内存,并且是通过信号量来控制
int main ()
{
int shm_id,msg_id,sem_id,i;
struct msgbuf readBuf;
char *shmaddr;
key_t key;
if((key = ftok(".",1)) < 0){
printf("ftok error\n");
exit(-1);
}
//1.创建共享内存
if((shm_id = shmget(key,1024*4, IPC_CREAT|0666)) == -1){
printf("shmget error\n");
exit(-1);
}
//2.连接共享内存
shmaddr = shmat(shm_id,0,0);
if(shmaddr < 0){
printf("shmat error\n");
exit(-1);
}
//3.创建消息队列
if((msg_id = msgget(key,IPC_CREAT|0777)) == -1){
printf("msgget error\n");
exit(-1);
}
//4.创新信号量
if((sem_id = semget(key,1,IPC_CREAT|0666)) == -1){
printf("semget errot\n");
exit(-1);
}
//5. 初始化信号量
union semun initsem;
initsem.val = 1; //刚刚开始是有锁的
if(semctl(sem_id,0,SETVAL,initsem) == -1){
printf("initsemctl error\n");
return -1;
}
while(1)
{
msgrcv(msg_id,&readBuf,sizeof(readBuf.mtext),888,0);
if(readBuf.mtext == 'q'){
printf("red from que: %c\n",readBuf.mtext);
break;
}
else if(readBuf.mtext == 'r'){
pGet(sem_id);
printf("red from que: %c\n",readBuf.mtext);
printf("shmat data:%s\n",shmaddr); //输出共享内存中的数据
vPut(sem_id);
}
}
printf("quit\n");
shmdt(shmaddr);// 断开与共享内存的连接
shmctl(shm_id,IPC_RMID,NULL);
msgctl(msg_id,IPC_RMID,NULL);
semctl(sem_id,0,IPC_RMID);
return 0;
}
mySemClient.c
#include<stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<stdlib.h>
#include <sys/types.h>
#include<sys/msg.h>
#include<sys/sem.h>
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext; /* message data */
};
void pGet(int sem_id){
struct sembuf sops;
sops.sem_num = 0;
sops.sem_op = -1;
sops.sem_flg = SEM_UNDO;
if(semop(sem_id,&sops,1) == -1){
printf("pGet failed!!\n");
exit(-1);
}
}
void vPut(int sem_id){
struct sembuf sops;
sops.sem_num = 0;
sops.sem_op = 1;
sops.sem_flg = SEM_UNDO;
if(semop(sem_id,&sops,1) ==-1){
printf("vPut failed!!\n");
exit(-1);
}
}
int main()
{
int shm_id,msg_id,sem_id,i=1;
char *shmaddr;
char data;
key_t key;
if((key = ftok(".",1)) == -1){
printf("ftok error\n");
exit(-1);
}
//1.创建共享内存
if((shm_id =shmget(key,1024*4,0)) == -1){
printf("shmget error\n");
exit(-1);
}
//2.连接共享内存
shmaddr = shmat(shm_id, 0, 0);
if(shmaddr < 0){
printf("shamt error\n");
exit(-1);
}
//3.创建消息队列
if((msg_id = msgget(key,0)) == -1){
printf("msgget error\n");
exit(-1);
}
//4.创新信号量
if((sem_id = semget(key,1,0)) ==-1){
printf("semget error\n");
exit(-1);
}
printf("---------send data---------\n");
printf("---------------------------\n");
struct msgbuf buf;
while(i){
printf("please intput:\n");
//gets(data);
scanf("%c",&data);
getchar();
switch(data){
case'r':
pGet(sem_id);
printf("data=%c\n",data);
buf.mtype = 888;
buf.mtext = 'r';
printf("intput shmaddr:\n");
scanf("%s",shmaddr);//向共享内存写入数据
getchar();
msgsnd(msg_id,&buf,sizeof(buf.mtext),0);
vPut(sem_id);
break;
case'q':
pGet(sem_id);
printf("send quit\n");
buf.mtype = 888;
buf.mtext = 'q';
msgsnd(msg_id,&buf,sizeof(buf.mtext),0);
i = 0;
vPut(sem_id);
break;
case's':
pGet(sem_id);
printf("s,success\n");
break;
case'p':
vPut(sem_id);
printf("p,success\n");
break;
}
}
shmdt(shmaddr);
return 0;
}