进程间的通信(IPC)对象

消息队列(message queue)

Quesion1

1)要求AB进程做通信

  1. A进程发送一句话,B进程接收打印

  2. 然后B进程发送给A进程一句话,A进程接收打印

    在基础上实现,AB进程能够随时收发数据

代码实现

A进程

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include<string.h>
#include <signal.h>
#include <unistd.h>
#define TYPE 1
#define TYPE2 2
struct msgbuf
{
	long mtype;
	char mtext[128];
};
int main(int argc,const char *argv[])
{
	//计算key值
	key_t key = ftok("./", 1);
	if(key < 0)
	{
		perror("ftok" );
		return -1;
	}
			printf("key=%#x\n",key);
		//创建一个消息队列
		int msqid = msgget(key, IPC_CREAT|0664);
		if(msqid < 0)
		{
			perror("msgget");
			return - 1;
		}

		printf("msqid=%d\n", msqid);
		//发送消息包
		pid_t pid;
		struct msgbuf snd;
		struct msgbuf rcv;
		ssize_t res =0;
		pid=fork();
		if(pid>0)
		{
			while(1)
			{
			//	printf("输入消息类型>>>");//手动获取消息类型
			//	scanf("%ld",&snd.mtype);
			//	getchar();
					snd.mtype=TYPE;//消息类型
				//	strcpy(snd.mtext,"1");
				printf("请输入>>>");
				fgets(snd.mtext,sizeof(snd.mtext),stdin);
				snd.mtext[strlen(snd.mtext)-1] = 0;
				//阻塞方式发送,消息队列满了,阻塞
				if(msgsnd(msqid,&snd,sizeof(snd.mtext),0)<0)
				{
					perror("msgsnd");
					return -1;
				}
				printf("消息包发送成功\n");
				if(strcmp(snd.mtext,"quit")==0)
				{
					kill(pid,2);
					exit(0);
				}

			}
		}
		if(pid==0)
		{
			while(1)
			{
				res=msgrcv(msqid,&rcv,sizeof(rcv.mtext),TYPE2,0);
				if(res<0)
				{
					perror("msgrcv");                                      
					return-1;
				}
				printf("res=%ld [%ld :%s]\n",res,rcv.mtype,rcv.mtext);
				if(strcmp(rcv.mtext,"quit")==0)
				{
					printf("接受到退出指令");
					kill(getppid(),2);
					exit(0);
				}

			}

		}
		system("ipcs -q");
		return 0;
	}

B进程

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include<string.h>
#include <signal.h>
#include <unistd.h>
#define TYPE 1
#define TYPE2 2

struct msgbuf
{
	long mtype;
	char mtext[128];
};
int main(int argc,const char *argv[])
{
	//计算key值
	key_t key = ftok("./", 1);
	if(key < 0)
	{
		perror("ftok" );
		return -1;
	}
			printf("key=%#x\n",key);
		//创建一个消息队列
		int msqid = msgget(key, IPC_CREAT|0664);
		if(msqid < 0)
		{
			perror("msgget");
			return - 1;
		}

		printf("msqid=%d\n", msqid);
		//发送消息包
		pid_t pid;
		struct msgbuf snd;
		struct msgbuf rcv;

		ssize_t res =0;
		pid=fork();
		if(pid>0)
		{
			while(1)
			{
				//printf("输入消息类型>>>");//手动获取消息类型
				//scanf("%ld",&snd.mtype);
				//getchar();
					snd.mtype=TYPE2;//消息类型
				//	strcpy(snd.mtext,"1");
				printf("请输入>>>");
				fgets(snd.mtext,sizeof(snd.mtext),stdin);
				snd.mtext[strlen(snd.mtext)-1] = 0;
				//阻塞方式发送,消息队列满了,阻塞
				if(msgsnd(msqid,&snd,sizeof(snd.mtext),0)<0)
				{
					perror("msgsnd");
					return -1;
				}
				printf("消息包发送成功\n");
				if(strcmp(snd.mtext,"quit")==0)
				{
					kill(pid,2);
					exit(0);
				}

			}
		}
		if(pid==0)
		{
		  while(1)
 {
     res=msgrcv(msqid,&rcv,sizeof(snd.mtext),TYPE,0);
     if(res<0)
     {
     perror("msgrcv");                                      
     return-1;
     }
     printf("res=%ld [%ld :%s]\n",res,rcv.mtype,rcv.mtext);
     if(strcmp(rcv.mtext,"quit")==0)
     {
         printf("接受到退出指令");
		 kill(getppid(),2);
         exit(0);
     }

 }
	
		}
		system("ipcs -q");
		return 0;
	}

运行现象

在这里插入图片描述

共享内存(shared memory)

Question2

  1. A进程写入一个整型,在该整型后,写入一个字符串
  2. B进程将共享内存中的整型以及字符串读取出来;

代码实现

输入程序

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<stdlib.h>
#include<string.h>
#include<sys/shm.h>
//a进程
int main(int argc, const char *argv[])
{
	//创建共享文件
	key_t key =ftok("./",1);
	if(key<0)
	{
		perror("ftok");
		return -1;
	}
 
	//创建共享内存
	
	int shmid=shmget(key,100,IPC_CREAT|0777);//在key值空间创建一个大小为100字节的共享空间,如果不存在,则创建,其权限为0777
	if(shmid<0)
	{
		perror("shmget");
		return -1;
	}
	printf("shmid =%d\n",shmid);
	//共享内存的映射
	void *shmaddr=shmat(shmid,NULL,0);
 
	//写入
	int wr_in;
	int *p=(int*)shmaddr;//用整形指针变量P接收共享内存的首地址
	printf("输入需要写入的整形数据>>>");
	scanf("%d",wr_in);
	getchar();//回收垃圾字符
	*p=12233;//由于P是整形指针变量,可以直接向其所指向的地址空间写入整形数据
 	char str[100];
	char *q=(char*)(p+1);//用字符型指针变量q接收存储整形变量后空余地址空间的首地址
	scanf("%s",str);
	strcpy(q,str);//向q指向地址空间中写入字符串
	system("ipcs -m");
 
 
	return 0;
}
 

输出程序

 #include<stdio.h>                                  
 #include<sys/types.h>                              
 #include<sys/ipc.h>                                
 #include<stdlib.h>                                 
 #include<string.h>                                 
 #include<stdio.h>                                  
 #include<sys/shm.h>                                
 //b进程                                            
 int main(int argc, const char *argv[])             
 {                                                  
     //创建共享文件                                 
     key_t key =ftok("./",5);                     
     if(key<0)                                      
     {                                              
         perror("ftok");                            
         return -1;                                 
     }                                              
                                                    
     //创建共享内存                                 
                                                    
     int shmid=shmget(key,32,IPC_CREAT|0777);       
     if(shmid<0)                                    
     {                                              
         perror("shmget");                          
         return -1;                                 
     }                                              
     printf("shmid =%d\n",shmid);                   
                         
                                                    
     //共享内存的映射                               
     void *shmaddr=shmat(shmid,NULL,0);             
                                                    
     //读出                                       
     int *p=(int*)shmaddr;//用整形指针变量P接收共享内存的首地址
                          
     printf("%d\n",*p);                                                                              
     char *q=(char*)(p+1);//用字符型指针变量q接收存储整形变量后空余地址空间的首地址
                         
     printf("%s\n",q);//以字符串形式打出指针变量q指向地址往后所存入的连续字符变量                             
         system("ipcs -m");     
 
     return 0;                                      
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值