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文件,不然就会一直读取空消息,疯狂刷屏

相关推荐
小小de风呀1 小时前
de风——【从零开始学习Linux】(九):进程基础 —— 从冯诺依曼体系到 fork 创建进程
linux·学习
晚风吹北巷3 小时前
Linux复习篇(自用)
linux·运维·服务器·1024程序员节
by209993 小时前
Linux 压缩传输、进程查看与权限管理
linux·经验分享·1024程序员节
无足鸟ICT4 小时前
【RHCA+】reboot命令(重启)
linux·运维·服务器·1024程序员节
DYWorker0015 小时前
第1课:基于正点原子RK3568开发板读懂Linux内核
linux·运维·网络
Android系统攻城狮5 小时前
Linux FFmpeg深度解析之avformat_open_input调用流程与实战(一)
linux·运维·ffmpeg·车载音视频·ffmpeg音视频·音视频进阶手册
吹什么轩5 小时前
linux系统复习:Ext 文件系统(一个文件在磁盘上到底长什么样)
linux·运维·服务器
吹什么轩6 小时前
linux系统复习:全景串联
linux·运维·服务器
m0_547486666 小时前
《Ubuntu Linux操作系统与实验教程》全套PPT课件2026
linux·ubuntu·操作系统