第四十三节 Linux系统编程-进程通信-消息队列(三)

-------------------------------------资源来源于网络,仅供自学使用,如有侵权,联系我必删.

第一:

消息队列 msg

• 消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级
• 对消息队列有写权限的进程可以向其中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。

 

使用 man 学习 msgget 等函数

消息队列主要有两个函数 msgrcv 和 msgsnd,一个接收一个发送。

 

1)使用命令“man 2 msgrcv”,如下图所示。

2)接着看一下相关函数,如下图所示。

3)分析一下 msgrcv 和 msgsnd 函数。

• 函数ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long
msgtyp,int msgflg)
– 参数msqid:消息队列的标识码
– 参数*msgp:指向消息缓冲区的指针
– 参数msgsz:消息的长短
– 参数msgflg:标志位
– 返回值:成功返回数据长度,错误返回-1

 

• 函数int msgsnd(int msqid, const void *msgp, size_t msgsz, int
msgflg)
– 参数msqid:消息队列的标识码
– 参数*msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用 户可定义的通用结构
– 参数msgsz:消息的长短
– 参数msgflg:标志位
– 返回值:成功返回0,错误返回-1

 

• 结构体msgp,是一个标准的通用结构
– struct msgstru{
long mtype; //大于0
char mtext[nbyte];}

 

• 函数int msgget(key_t key, int msgflg)
– 参数“key”:消息队列关联的标识符
– 参数“msgflg”:消息队列的建立标志和存取权限。IPC_CREAT 如果内核中没有此队列则创建它;IPC_EXCL 当和IPC_CREAT 一起使用时,如果队列已经存在,则失败
– 返回值:执行成功则返回消息队列的标识符,否则返回-1

 

• 函数ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg)
– 参数msgtyp
• msgtyp等于0 ,则返回队列的最早的一个消息
• msgtyp大于0,则返回其类型为mtype的第一个消息
• msgtyp小于0,则返回其类型小于或等于mtype参数的绝对值的最小的一个消息
– 参数msgflg:标志位为0,则表示忽略

 

第二:

msgget 函数例程

编写简单的 msgsend.c 和 msgreceive.c 文件实现消息队列

文件 msgsend.c

#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <string.h>  
#include <sys/msg.h>  
#include <errno.h>  
  
#define MAX_TEXT 512  
struct msg_st  
{  
    long int msg_type;  
    char text[MAX_TEXT];  
};  
  
int main()
{  
    int running = 1;  
    struct msg_st data;  
    char buffer[BUFSIZ];  
    int msgid = -1;  
  
    //建立消息队列  
    msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
    if(msgid == -1)  
    {  
        fprintf(stderr, "msgget failed with error: %d\n", errno);  
        exit(EXIT_FAILURE);  
    }  
  
    //向消息队列中写消息,直到写入end  
    while(running)  
    {  
        //输入数据  
        printf("Enter some text: ");  
        fgets(buffer, BUFSIZ, stdin);  
        data.msg_type = 1;    //注意2  
        strcpy(data.text, buffer);  
        //向队列发送数据  
        if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)  
        {  
            fprintf(stderr, "msgsnd failed\n");  
            exit(EXIT_FAILURE);  
        }  
        //输入end结束输入  
        if(strncmp(buffer, "end", 3) == 0)  
            running = 0;  
        sleep(1);  
    }  
    exit(EXIT_SUCCESS);  
}

 

文件 msgreceive.c

#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <string.h>  
#include <errno.h>  
#include <sys/msg.h>  
  
struct msg_st
{  
    long int msg_type;  
    char text[BUFSIZ];  
};  
  
int main()  
{  
    int running = 1;  
    int msgid = -1;  
    struct msg_st data;  
    long int msgtype = 0; //注意1  
  
	
  
    //建立消息队列  
    msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
    if(msgid == -1)  
    {  
        fprintf(stderr, "msgget failed with error: %d\n", errno);  
        exit(EXIT_FAILURE);  
    }  
    //从队列中获取消息,直到遇到end消息为止  
    while(running)  
    {  
        if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)  
        {  
            fprintf(stderr, "msgrcv failed with errno: %d\n", errno);  
            exit(EXIT_FAILURE);  
        }  
        printf("You wrote: %s\n",data.text);  
        //遇到end结束  
        if(strncmp(data.text, "end", 3) == 0)  
            running = 0;  
    }  
    //删除消息队列  
    if(msgctl(msgid, IPC_RMID, 0) == -1)  
    {  
        fprintf(stderr, "msgctl(IPC_RMID) failed\n");  
        exit(EXIT_FAILURE);  
    }  
    exit(EXIT_SUCCESS);  
} 

 

第三:

 编译运行测试

1)在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录
“/home/linuxsystemcode/pc”,将源码 msgsend.c 和 msgreceive.c 拷贝进去,如下图所示。

2)使用命令
“arm-none-linux-gnueabi-gcc -o msgsend msgsend.c -static”编译 msgsend 文件,
“arm-none-linux-gnueabi-gcc -o msgreceive msgreceive.c -static”编译 msgreceive 文件,
如下图所示,使用命令“ls”可以看到生成了 msgsend 和 msgreceive 可执行文件。

3)将编译成的可执行文件 msgsend 和 msgreceive拷贝到挂载点

4)先在后台运行接收程序 msgreceive,如下图所示

5)接着运行发送程序 msgsend,如下图所示。

 

6)如下图所示,运行发送程序,提醒用户输入字符。输入除 end 以外其他任意字符串,都会
接着提示继续输入,最后输入 end,两个程序都结束。

7)接着使用命令“jobs”,如下图所示,程序已经结束。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值