linux进程通信---消息队列

消息队列:消息队列是一些消息的列表,用户可以从消息队列中读取和添加消息,消息队列具有FIFO的特性,但可以实现消息的随机查询,比FIFO有更大的优势,这些消息都是存在于内核中,由“队列ID”来标识

消息队列的实现包括创建或打开消息队列,添加消息,读取消息,控制消息四种操作

创建或打开消息:使用msgget(),这里创建的消息队列的数量受到系统消息队列数量的限制

添加消息:使用msgsnd(),他把消息添加到消息队列的末尾

读取消息:使用msgrcv(),他把消息从消息队列中取走,与FIFO不同的是他可以取走某一条消息

控制消息:使用msgctl()控制消息队列,根据参数的不同可以完成多项功能

msgget()函数语法如下:

msgsnd()函数语法如下:

msgrcv()函数语法如下:

msgctl()函数语法如下:

这个例子说的两个进程通过消息队列进行通信:

发送端代码:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUFFER_SIZE 512
struct message
{
    long msg_type ;//消息类型
    char msg_text[BUFFER_SIZE] ;//消息内容
};

int main()
{
    int qid ;
    key_t key ;
    struct message msg ;
    //ftok()函数根据路径和关键字生产标准的key
    if ((key = ftok(".", 'a')) == -1)
    {
        perror("ftok") ;
        exit(1) ;
    }
    //创建消息队列
    if ((qid = msgget(key, IPC_CREAT|0666)) == -1)
    {
        perror("msgget") ;
        exit(1) ;
    }
    printf("open queue %d\n", qid) ;
    while(1)
    {
        printf("Enter some message to the queue:") ;
        if (fgets(msg.msg_text, BUFFER_SIZE, stdin) == NULL)
        {
            puts("no message") ;
            exit (1) ;
        }
        //将消息类型设置成进程的id
        msg.msg_type = getpid() ;
        //向消息队列中添加消息
        if (msgsnd(qid, &msg, strlen(msg.msg_text), 0) < 0)
        {
            perror("messaged posted") ;
            exit(1) ;
        }
        if (strncmp(msg.msg_text, "quit", 4) == 0)
        {
            break ;
        }
    }
    exit(0) ;
}

接收端:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUFFER_SIZE 512
struct message
{
    long msg_type ;
    char msg_text[BUFFER_SIZE] ;
};
int main()
{
    int qid ;
    key_t key ;
    struct message msg ;
    if ((key = ftok(".", 'a')) == -1)
    {
        perror("ftok") ;
        exit(1) ;
    }
   if ((qid = msgget(key, IPC_CREAT|0666)) == -1)
    {
        perror("msgset") ;
        exit(1) ;
    }
    printf("open queue%d\n", qid) ;
    do
    {
        memset(msg.msg_text, 0, BUFFER_SIZE) ;
        //从消息队列中获取消息
        if (msgrcv(qid, (void *)&msg, BUFFER_SIZE, 0, 0) < 0)
        {
            perror("msgrcv") ;
            exit(1) ;
        }
        printf("the message from process %d:%s", msg.msg_type, msg.msg_text) ;

    }while(strncmp(msg.msg_text, "quit", 4)) ;
    //删除消息队列
    if ((msgctl(qid, IPC_RMID, NULL)) < 0)
    {
        perror("msgctl") ;
        exit(1) ;
    }
    exit(0) ;
}
运行结果如下:

发送端:

接接收端:

由此可以看出两个进程使用id为65535的消息队列进行通信,消息队列内核自动实现了同步,所以不需要额外提供同步机制来自http://bbs.csdn.net/topics/300199658

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux进程通信的方式有很多种,其中一种常用的方式是通过消息队列(Message Queue)进行通信消息队列是一种进程通信的机制,它允许一个进程向另一个进程发送消息,而不需要直接的函数调用。在Linux系统中,消息队列是由内核维护的一段共享内存,其中的消息按照一定的顺序进行存储和读取。进程可以通过消息队列发送和接收消息,从而实现进程间的通信Linux提供了一组系统调用函数来操作消息队列,主要有以下几个函数: - `msgget(key, flags)`:创建或获取一个消息队列。key是用于标识消息队列的关键字,flags是创建标志。 - `msgsnd(msqid, msgp, msgsz, msgflg)`:向指定的消息队列发送消息。msqid是消息队列标识符,msgp是指向要发送的消息结构体的指针,msgsz是消息的大小,msgflg是发送标志。 - `msgrcv(msqid, msgp, msgsz, msgtyp, msgflg)`:从指定的消息队列中接收消息。msqid是消息队列标识符,msgp是指向接收到的消息结构体的指针,msgsz是消息的大小,msgtyp是消息类型,msgflg是接收标志。 - `msgctl(msqid, cmd, buf)`:对消息队列进行控制操作。msqid是消息队列标识符,cmd是控制命令,buf是用于传递参数的缓冲区。 以上是消息队列的基本操作函数,通过它们可以实现进程间的消息传递和通信。需要注意的是,消息队列的使用需要对消息的格式进行设计,并且发送和接收进程需要约定好消息的类型和大小等参数。 希望以上信息能够对您有所帮助。如果您还有其他问题,请随时提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值