linux——消息队列进程间通信

ftok函数

复制代码
key_t ftok( char * fname, int id ) 
//系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值。通常情况下,该id值通过ftok函数得到。 
参数: 
        fname就时你指定的文件名(该文件必须是存在而且可以访问的)。 
        id是子序号, 虽然为int,但是只有8个比特被使用(0‐255)。 
返回值: 
        当成功执行的时候,一个key_t值将会被返回,否则 ‐1 被返回。 

1、半双工

创建一个msg_write.c

复制代码
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include<string.h>

struct msgbuf
{
        long mtype;
        char mtest[128];
        char ID[4];
};

int main()
{
        struct msgbuf sendbuf;
        int msgid;
        key_t key;

        key = ftok("a.c",1);

        msgid = msgget(key,IPC_CREAT|0755);

        if(msgid == -1)
        {
                printf("creat message queue failed\n");
                return -1;
        }
        system("ipcs -q");
        printf("creat message queue succeed! msgid = %d\n",msgid);

        //int msgbuf
        sendbuf.mtype = 100;
        while(1)
        {
                memset(sendbuf.mtest,0,128);
                printf("please input to message queue:\n");
                fgets(sendbuf.mtest,128,stdin);
                msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.mtest),0);
        }
        return 0;
}

在创建一个msg_read.c

复制代码
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include<string.h>

struct msgbuf
{
	long mtype;
	char mtest[128];
	char ID[4];
};

int main()
{
	struct msgbuf sendbuf,readbuf;
	int msgid;
	key_t key;
	int readret;

	key = ftok("a.c",1);

	msgid = msgget(key,IPC_CREAT|0755);

	if(msgid == -1)
	{
		printf("creat message queue failed\n");
                return -1;
        }
        system("ipcs -q");
        printf("creat message queue succeed! msgid = %d\n",msgid);

	//int msgbuf
	sendbuf.mtype = 100;
	while(1)
	{
		memset(readbuf.mtest,0,128);
		readret = msgrcv(msgid,(void *)&readbuf,128,100,0);
		printf("message is:%s\n",readbuf.mtest);
		printf("total is %d byte\n",readret);
	}
	return 0;
}

可以实现进程间通信,但这个是半双工的,只能write写read读

2、全双工

创建两个文件,msg_service.c

复制代码
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include<string.h>
#include <unistd.h>

struct msgbuf
{
	long mtype;
	char mtest[128];
	char ID[4];
};

int main()
{
	struct msgbuf sendbuf,readbuf;
	int msgid;
	key_t key;
	pid_t pid;

	key = ftok("a.c",1);

	msgid = msgget(key,IPC_CREAT|0755);

	if(msgid == -1)
	{
		printf("creat message queue failed\n");
		return -1;
	}
	system("ipcs -q");
	printf("creat message queue succeed! msgid = %d\n",msgid);

	//int msgbuf
	sendbuf.mtype = 100;

	pid = fork();
	//parent process write 100
	if(pid>0)
	{

		while(1)
		{
			memset(sendbuf.mtest,0,128);
			printf("please input to message queue:\n");
			fgets(sendbuf.mtest,128,stdin);
			msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.mtest),0);
		}
	}
	//child process read 200
	if(pid==0)
	{
		while(1)
		{
			memset(readbuf.mtest,0,128);
			msgrcv(msgid,(void *)&readbuf,128,200,0);
			printf("receive byte from message queue is:%s\n",readbuf.mtest);
		}
	}
	return 0;
}

核心结构

  1. ftok("a.c",1) 拿钥匙、msgget 建同一个消息队列
  2. fork() 拆分两个进程:
    • 父进程:负责发 100 类型消息
    • 子进程:负责收 200 类型消息

创建msg_client.c

复制代码
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include<string.h>
#include <unistd.h>

struct msgbuf
{
	long mtype;
	char mtest[128];
	char ID[4];
};

int main()
{
	struct msgbuf sendbuf,readbuf;
	int msgid;
	key_t key;
	pid_t pid;

	key = ftok("a.c",1);

	msgid = msgget(key,IPC_CREAT|0755);

	if(msgid == -1)
	{
		printf("creat message queue failed\n");
		return -1;
	}
	system("ipcs -q");
	printf("creat message queue succeed! msgid = %d\n",msgid);

	//int msgbuf
	sendbuf.mtype = 200;

	pid = fork();
	//child process write 200
	if(pid==0)
	{

		while(1)
		{
			memset(sendbuf.mtest,0,128);
			printf("please input to message queue:\n");
			fgets(sendbuf.mtest,128,stdin);
			msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.mtest),0);
		}
	}
	//parent process read 100
	if(pid>0)
	{
		while(1)
		{
			memset(readbuf.mtest,0,128);
			msgrcv(msgid,(void *)&readbuf,128,100,0);
			printf("receive byte from message queue is:%s\n",readbuf.mtest);
		}
	}
	return 0;
}
  • 子进程:负责发 200 类型消息
  • 父进程:负责收 100 类型消息

成功实现,值得注意的是,一定要提前创建a.c文件,不然就会一直读取空消息,疯狂刷屏

相关推荐
说再见再也见不到6 分钟前
华为交换机端口隔离(port-isolate)
linux·服务器·网络·华为·交换机·端口隔离·port-isolate
daemon.qiang14 分钟前
Ubuntu 20.04+安装JFrog CLI超详细指南
linux·运维·ubuntu
湖城彭于晏14 分钟前
VMware Ubuntu 固定IP + 上网 + 远程访问 完整教程
linux·ubuntu·vmware
小夏子_riotous14 分钟前
Docker学习路径——6、简单微服务
linux·运维·服务器·docker·微服务·容器·云计算
剪刀石头布Cheers15 分钟前
Ubuntu Hermes安装关键步骤
linux·运维·ubuntu·ai·agent·hermes
雕刻刀21 分钟前
pip离线安装
linux·python·pip
JoyCong199822 分钟前
告别频繁输入密码!ToDesk自动解锁功能,实现远程办公“无感”连接
大数据·linux·服务器·网络·电脑·远程操作
楼田莉子27 分钟前
仿muduo库的高并发服务器——正则表达式与any类介绍及其简单模拟实现
linux·服务器·c++·学习·设计模式
IT摆渡者29 分钟前
Linux 巡检脚本BASH
linux·运维·bash
minji...30 分钟前
Linux 网络套接字编程(二)从 0 到 1 实现 UDP 回声服务器,recvfrom,sendto
linux·运维·网络·单片机·udp