IPC——消息队列双向通行

消息队列提供了一个进程向另一个进程发送数据块的方法,每个数据块都被认为是有一个类型的,这个类型下文中是用常量is_client_snd和is_server_snd来表示的

消息队列相比管道来说的优点是避免了阻塞。

系统调用函数:

  1. #include<sys/types.h>

    #include<sys/ipc.h>

原型:key_t ftok(const char* pathname,int proj_id);

参数:pathname为一个已存在的、可获得信息的文件的全路径(必须是已经存在的文件)

proj_id为任意低8位不为0的数(因为要取它的低8位)

ftok算法

返回值:成功返回一个key值     失败返回-1

2.#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/msg.h>

原型:int msgget(key_t key,int msgflg);

参数:key可由ftok获得

flag可取三个值 IPC_CREAT  IPC_EXCL   IPC_CREAT|IPC_EXCL

IPC_CREAT 创建一个消息队列并返回队列的标识,如果该队列已存在则直接返回该标识

IPC_EXCL  本身并没多大意思,通常和IPC_CREAT一起使用

IPC_CREAT|IPC_EXCL 创建消息队列,如果该队列已经存在则直接返回-1报错,保证资源是              新建的而不是打开的

返回值:成功返回队列标识 _msg_id   失败返回-1

3.#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/msg.h>

接收消息:ssize_t msgrcv(int msgid, const void *msgp,size_t msgsz,int msgtyp,int msgflg);

发送消息:int msgsnd(int msgid,const void *msgp,size_t msgsz,int msgflg));

参 数:   msg_id为消息队列的标识, msgp为指向消息缓冲区的指针(用户可自己制定的通用结构)

msgsz为消息的大小,msftyp为从队列中取消息的类型,为0可以取任何消息,

msgflg指明当消息队列中没消息时应该做的指示,0为阻塞,IPC_NOWAIT则直接返回-1;

用到的命令:

ipcs -q        //查看系统中存在的消息队列

ipcrm -q key值   //删除指定的key值的消息队列

//comm.h
#ifndef _MSG_QUEUE_
#define _MSG_QUEUE_

#include<stdio.h>
#include<sys/ipc.h>
#include<sys/types.h>
#include<stdlib.h>
#include<sys/msg.h>
#include<string.h>

#define _PATH_ "/tmp/.msg"
#define _PROJ_ID_ 0x55

#define _MSG_SIZE_ 1024

extern const long is_server_snd;
extern const long is_client_snd;

typedef struct _msg_info _msg_info;
struct _msg_info
{
    int mtype;
    char mtext[_MSG_SIZE_];
};

static int comm_msg(int flag);
int creat_msg_queue();
int get_msg_queue();
int destroy(int msg_id);

#endif
//comm.c
#include"comm.h"

const long is_server_snd=1;
const long is_client_snd=2;

static int comm_msg(int flag)
{
    key_t _key=ftok(_PATH_,_PROJ_ID_);
    if(_key<0){
        perror("ftok");
        return -1; 
    }   
    int msg_id= msgget(_key,flag);
    if(msg_id<0){
        perror("msgget");
        return -1; 
    }   
    else
        return msg_id;
}

int creat_msg_queue()
{
    return comm_msg(IPC_CREAT|IPC_EXCL);
}

int get_msg_queue()
{
    return comm_msg(IPC_CREAT);
}

int destroy(int msg_id)
{
    return msgctl(msg_id,IPC_RMID,NULL);
}
//server.c
#include"comm.h"

int main()
{
    int _msg_id=creat_msg_queue();
    _msg_info msginfo;
    while(1){
        msginfo.mtype=is_client_snd;
        memset(msginfo.mtext,‘\0‘,sizeof(msginfo.mtext));
        if(msgrcv(_msg_id,&msginfo,sizeof(msginfo.mtext),is_client_snd,0)<0){
            perror("msgrcv");
        }
        else{
            printf("client say# %s",msginfo.mtext);
        }
        msginfo.mtype=is_server_snd;
        memset(msginfo.mtext,‘\0‘,sizeof(msginfo.mtext));
        read(0,msginfo.mtext,sizeof(msginfo.mtext));
        if(msgsnd(_msg_id,&msginfo,sizeof(msginfo),0)<0){
            perror("msgsnd");
        }
    }
    if(destory(_msg_id)!=0){
        perror("destory failed!\n");
    }
    else
        printf("destory success!\n");

    return 0;
}

//client.c
#include"comm.h"

int main()
{
    int _msg_id= get_msg_queue();
    _msg_info msginfo;
    while(1){
        memset(msginfo.mtext,‘\0‘,sizeof(msginfo.mtext));
        msginfo.mtype=is_client_snd;
        if(read(0,msginfo.mtext,sizeof(msginfo.mtext))>=0){
            if(msgsnd(_msg_id,&msginfo,sizeof(msginfo.mtext),0)<0){
                perror("msgsnd");
            }
        }
        memset(msginfo.mtext,‘\0‘,sizeof(msginfo.mtext));
        if(msgrcv(_msg_id,&msginfo,sizeof(msginfo),is_server_snd,0)<0){
            perror("msgrcv");
        }
        else{
            printf("server say# %s",msginfo.mtext);
        }
    }   
    return 0;
 }
    
  
//Makefile
.PHONY:all
all:server client
server:server.c comm.c
    gcc -o server server.c comm.c
client:client.c comm.c
    gcc -o client client.c comm.c

.PHONY:clean
clean:
    rm -rf server client
时间: 2024-08-08 16:13:26

IPC——消息队列双向通行的相关文章

Linux进程通信(二)IPC消息队列

一.什么是消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法.每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构.我们可以通过发送消息来避免命名管道的同步和阻塞问题.但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制. Linux用宏MSGMAX和MSGMNB来限制一条消息的最大长度和一个队列的最大长度MSGMNI来限制消息队列的总数. 二.IPC对象数据结构 内核为每个IPC对象维护一个数据结构(/usr/include/linux/ip

IPC: 消息队列

#################################################### 消息队列   消息队列分为: 1.posix消息队列:可以在同一主机上有亲缘关系或无亲缘关系的进程间使用. 2.system v消息队列:同上. 消息队列有随内核的持续性. ----------------------------------------------------------- posix消息队列: gcc -lrt #include <mqueue.h> #include

IPC——消息队列

Linux进程间通信——使用消息队列 下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信——使用命名管道 一.什么是消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法.消息队列是消息的链接表,存放在内核中并由消息队列标识符标识.  每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构.我们可以通过发送消息来避免命名管道的同步和阻塞问题(命名管道要读端和写端

Linux IPC 消息队列

1. Posix 消息队列 /* mq_open - open a message queue */#include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode constants */ #include <mqueue.h> mqd_t mq_open(const char *name, int oflag); mqd_t mq_open(const char *name, i

IPC 消息队列 一

消息队列可以认为是一个消息链表,某个进程往一个消息队列中写入消息之前,不需要另外某个进程在该队列上等待消息的达到,这一点与管道和FIFO相反.Posix消息队列与System V消息队列的区别如下:1. 对Posix消息队列的读总是返回最高优先级的最早消息,对System V消息队列的读则可以返回任意指定优先级的消息.2. 当往一个空队列放置一个消息时,Posix消息队列允许产生一个信号或启动一个线程,System V消息队列则不提供类似的机制. Posix消息队列操作函数如下: #includ

进程间通信IPC:消息队列,信号量,共享内存

2015.3.4星期三 阴天 进程间通信:IPC 文件对象:记录文件描述符,文件开关等 IPC标示符:系统全局的流水号两个进程要通信,打开的是唯一的对象进行通讯,通过key操作 XSI IPC:消息队列,信号量,共享内存. ipcs 查看ip对象共享内存,信号量,消息队列等信息ipcrm 删除一个IP对象 Linux为用户提供了完善的,强大的网络功能完善的内置网络:其他操作系统不包含如此紧密的和内核结合在一起的网络部分 共享内存标示符的获取有两种方法:ftok(pathname,id)另一个是K

System V IPC 之消息队列

消息队列和共享内存.信号量一样,同属 System V IPC 通信机制.消息队列是一系列连续排列的消息,保存在内核中,通过消息队列的引用标识符来访问.使用消息队列的好处是对每个消息指定了特定消息类型,接收消息的进程可以请求接收下一条消息,也可以请求接收下一条特定类型的消息. 相关数据结构 与其他两个 System V IPC 通信机制一样,消息队列也有一个与之对应的结构,该结构的定义如下: struct msqid_ds { struct ipc_perm msq_perm; struct m

Chromium的IPC消息发送、接收和分发机制分析

由于Chromium采用多进程架构,因此会涉及到进程间通信问题.通过前面一文的学习,我们知道Browser进程在启动Render进程的过程中会建立一个以UNIX Socket为基础的IPC通道.有了IPC通道之后,接下来Browser进程与Render进程就以消息的形式进行通信.我们将这种消息称为IPC消息,以区别于线程消息循环中的消息.本文就分析Chromium的IPC消息发送.接收和分发机制. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! Chrom

第15章 进程间通行 15.6 XSI IPC 15.7 消息队列

15.6 XSI IPC (1)3种称作XSI IPC的IPC是: 1)消息队列 2)信号量 3)共享存储器 (2)标识符和键 1)标识符:是一个非负整数,用于引用IPC结构.是IPC对象的内部名. 2)键:IPC对象的外部名.可使多个合作进程能够在同一IPC对象上汇聚. (3)IPC_PRIVATE键: 用于创建一个新的IPC结构.不能指定此键来引用一个现有的IPC结构. (4)ftok函数: 由一个路径名和项目ID产生一个键. (5)ipc_perm结构体 规定了ipc结构的权限和所有者.