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、删除消息队列
************************************************************/
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步骤交给子进程做,提高效率
************************************************************/
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;
}
#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
#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
#include
#include
#if USE_FILE_CTL
#include
#endif // USE_FILE_CTL
#if USE_TIME
#include
#endif // USE_TIME
#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