【ARM&Linux】消息队列的简单使用

2019-07-12 20:29发布

class="markdown_views prism-atelier-sulphurpool-light">

《Linux下消息队列的使用笔记》


【代码及说明】

/**************************************************************************************** * 文件名: a_process.c * 创建者: * 时 间: * 联 系: * 简 介: *****************************************************************************************/ /*********************************************************** 函数学习: 1、创建消息队列: int msgget(key_t key, int msgflg); 2、发送消息: int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 参数一:消息id 参数二: 数据, 固定格式: struct mymsg{ long mtype; //消息类型 char mtext[512] //消息数据 }; 参数三:消息数据长度,例如上面的512 参数四:标志 返回值: 失败-1 成功0 3、接收消息: ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); 参数一:消息队列id 参数二:存储消息的结构 参数三:消息数据的大小 参数四:消息类型 = 0 时:忽略类型,直接取第一个消息 > 0 时: 返回消息队列中类型为type的第一个消息 < 0 时: 返回消息类型值小于或等于type绝对值的消息,如果此类有若干个,取最小的 参数五:标志 返回值: 失败-1 成功返回消息数据的数据量(mtext里面) 4、设置消息队列:int msgctl(int msqid, int cmd, struct msqid_ds *buf); 参数一:消息队列id 参数二:命令 参数三:存取消息队列信息的结构 删除消息队列 : msgctl(msgid, IPC_RMID, NULL); 【综合实例】: A进程获取键盘输入->构造成消息->添加到消息队列->发送 B进程->取出消息队列->打印消息 a_process.c 进程执行流程: 1、创建消息队列 2、获取键盘输入,要求用户输入两个信息 : 消息类型和消息数据,之后构造成一条消息 3、发送到消息队列 4、删除消息队列 ************************************************************/ #include "mytype.h" #define MSG_SIZE 1024*1 typedef struct{ long type; char data[MSG_SIZE]; }MY_MSG; int main() { MSG_QUEUE_USE msg_use; MY_MSG mymsg; bool running = true; char buf[128]; long msg_type; // 1.创建消息队列 msg_use.key = ftok("/bin", 1); if((msg_use.msgid=msgget(msg_use.key, IPC_CREAT)) < 0) { DEBUG_ERROR("msg queue creat failed . "); exit(EXIT_FAILURE); } // 2.循环 while(running) { // 3.1 获取消息类型 DEBUG_PRINTF("Please input msg type, 0 for quit : "); scanf("%ld", &msg_type); if(msg_type == 0) //如果消息类型为0,则退出循环 { running = false; break; } // 3.2 获取数据 DEBUG_PRINTF("Please input msg : "); scanf("%s", buf); // 3.3 构造消息 mymsg.type = msg_type; strcpy(mymsg.data, buf); // 4.发送消息 msgsnd(msg_use.msgid, &mymsg, sizeof(MY_MSG), 0); } // 5.删除消息队列 if( msgctl(msg_use.msgid, IPC_RMID, NULL) == 0) { DEBUG_INFO("delete msg queue successful . "); } return 0; } /**************************************************************************************** * 文件名: b_process.c * 创建者: * 时 间: * 联 系: * 简 介: *****************************************************************************************/ /*********************************************************** b_process.c 执行流程: 1.打开消息队列 2.接受消息队列数据 3.打印数据 2、3步骤交给子进程做,提高效率 ************************************************************/ #include "mytype.h" #define MSG_SIZE 1024*1 typedef struct{ long type; char data[MSG_SIZE]; }MY_MSG; void childprocess(const MSG_QUEUE_USE* const msg_use) { MY_MSG mymsg; while(1) { // 1、接收消息队列的消息 msgrcv(msg_use->msgid, &mymsg, sizeof(MY_MSG), 0, 0); //参数三设置为0,表示始终取消息队列中的第一个消息 // 2、打印数据 DEBUG_PRINTF("msg data is : %s ", mymsg.data); } } int main() { int cpid; MSG_QUEUE_USE msg_use; int i; // 1.获取消息队列 msg_use.key = ftok("/bin", 1); if((msg_use.msgid=msgget(msg_use.key, IPC_EXCL)) < 0) { DEBUG_ERROR("msg queue get failed . "); exit(EXIT_FAILURE); } DEBUG_INFO("start fork ... "); // 创建三个子进程 for(i=0; i<3; i++) { cpid = fork(); if(cpid < 0) //创建失败 { DEBUG_ERROR("creat child process %d failed . ", i); }else if(cpid == 0) //子进程 { childprocess(&msg_use); } } // 父进程退出 return 0; } /**************************************************************************************** * 文件名: mytype.h * 创建者: Kun * 时 间: 2018/0/12 * 联 系: 153471503@qq.com * 简 介: linux常用类型定义 *****************************************************************************************/ #ifndef _MYTYPE_H_ #define _MYTYPE_H_ //--------------------------< 预添加头文件包含 >----------------------// #define USE_TIME 0 #define USE_SIGNAL 0 #define USE_SHARE_MEMORY 0 #define USE_SEMAPHORE 0 #define USE_MSG_QUEUE 1 #define USE_FILE_CTL 0 //-------------------------------< end ----------------------------// //---------------------------< includes >---------------------------// // c标准库头文件 #include #include #include // 信号使用相关头文件 #if USE_SIGNAL #include #endif // USE_SIGNAL // 信号量操作相关头文件 #if USE_SEMAPHORE #include #include #endif // USE_SEMAPHORE // 共享内存操作相关头文件 #if USE_SHARE_MEMORY #include #endif // USE_SHARE_MEMORY // 消息队列相关头文件 #if USE_MSG_QUEUE #if !USE_SEMAPHORE #include #endif #include #endif // USE_MSG_QUEUE // 系统调用式文件编程头文件 #include // 该文件所定义的接口通常都是大量针对系统调用的封装, // 如 fork、pipe 以及各种 I/O 原语(read、write、close 等等)。 #include // linux系统中类型定义相关头文件 #include // 文件状态,是unix/linux系统定义文件状态所在的伪标准头文件。 #if USE_FILE_CTL #include #endif // USE_FILE_CTL #if USE_TIME // 时间编程相关头文件 #include #endif // USE_TIME //-------------------------< includes end >-------------------------// // bool类型定义 #ifndef bool typedef unsigned int bool; #endif enum { true = 1, false = !true }; // 常用无符号数据类型定义 typedef unsigned int uint; typedef unsigned char uchar; typedef unsigned short ushort; //----------------------< 调试信息输入相关宏定义 >----------------------// #define DEBUG_INFO(...) printf("Info: "); printf(__VA_ARGS__) #define DEBUG_ERROR(...) printf("Error: "); printf(__VA_ARGS__) #define DEBUG_WARNING(...) printf("Warning: "); printf(__VA_ARGS__) #define DEBUG_PRINTF(...) printf(__VA_ARGS__) //------------------------------------------------------------------// // 信号量使用封装结构 #if USE_SEMAPHORE typedef struct sem_use SEM_USE; struct sem_use { int semid; key_t key; struct sembuf sops; }; #endif // USE_SEMAPHORE // 共享内存使用封装结构 #if USE_SHARE_MEMORY typedef struct shmem_use SHMEM_USE; struct shmem_use { int shmid; key_t key; }; #define BUF_SIZE 1024*1 //共享内存大小 typedef struct shmem_area SHMEM_AREA; struct shmem_area { bool isnull; char data[BUF_SIZE]; }; #endif // USE_SHARE_MEMORY // 消息队列使用封装结构 #if USE_MSG_QUEUE typedef struct msg_queue_use MSG_QUEUE_USE; struct msg_queue_use{ key_t key; int msgid; }; #endif // USE_MSG_QUEUE #endif // _TYPE_H_

【运行结果】

【Makefile】

这里写图片描述

【结果】

这里写图片描述

end