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

相关推荐
kebidaixu19 分钟前
BCU 平台 RS485 驱动适配:从 THVD1406 到 ISO3082
linux
谢平康3 小时前
解决用 rm 报bash: /usr/bin/rm: Argument list too long错
linux·运维·运维开发
hj2862514 小时前
Linux 网络服务综合笔记(概念 + 命令 + 实操案例)2
linux·运维·网络
what_20184 小时前
Linux 磁盘 (查看、划分、inode)
linux·运维·服务器
2739920295 小时前
GDB调试(Linux)
linux
凡人叶枫5 小时前
Effective C++ 条款23:宁以 non-member、non-friend 替换 member 函数
linux·开发语言·c++·嵌入式开发
不会C语言的男孩5 小时前
Linux 系统编程 · 第 4 章:文件属性与元数据
linux·c语言·开发语言
小生不才yz6 小时前
Shell脚本精读 · S02-03 | 词拆分、通配符与未加引号的变量
linux
2601_961845426 小时前
法考真题及答案解析|历年真题|资料已整理
linux·windows·ubuntu·macos·centos·gnu
A_humble_scholar6 小时前
Linux(七)调度器:从硬件矛盾到进程切换的底层逻辑
linux·服务器·网络