linux消息队列,共享内存,信号量综合运用

关于对消息队列,共享内存,信号量的具体介绍
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;
}

猜你喜欢

转载自blog.csdn.net/qq_46777053/article/details/113178214
今日推荐