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

相关推荐
嵌入式学习菌2 小时前
内网穿透全闭环实操指南
linux·开发语言·php
Yupureki2 小时前
《Linux网络编程》2.Socket编程(UDP/TCP)
linux·服务器·c语言·网络·c++·tcp/ip·udp
竹之却2 小时前
【Linux】内网穿透原理
linux·服务器·网络·frp·内网穿透·p2p·xtcp
欲盖弥彰13142 小时前
Linux设备驱动 -- TMP75AIDR驱动移植
linux·驱动开发·驱动·驱动移植·嵌入式linux驱动·tmp75aidr
辰痕~2 小时前
数据结构-算法
linux
桦02 小时前
【Linux复习】:基础指令/常用工具
linux
HalvmånEver2 小时前
Linux:基于TCP Socket的在线翻译
linux·运维·服务器·网络·学习·tcp/ip
BIBI20492 小时前
VirtualBox 7.x 安装 Ubuntu 24 及增强功能配置、克隆虚拟机教程
linux·windows·ubuntu·环境搭建·安装教程·最佳实践·virtualbox
weixin_462901972 小时前
HICKPI主板h618 Ubuntu / Armbian 镜像 SD安装
linux·运维·ubuntu