资讯专栏INFORMATION COLUMN

Linuxc - 消息队列

lansheng228 / 785人阅读

摘要:用于控制当前消息队列满或队列消息到达系统范围的限制时将要发生的事情返回值成功,消息数据的一分副本将被放到消息队列中,并返回,失败时返回用来从一个消息队列获取消息是由函数返回的消息队列标识符。

linuxc-消息队列

​ --详情见《unix环境高级编程》15.7小节

​ 在《unix环境高级编程》15.7小节最后,总结了消息队列的优缺点。结论是,在新的应用程序中不应当再使用它们。确实是这样,追求高效,我们可以用共享内存,追求方便我们可以用管道或者UNIX域,消息队列就是处于这种尴尬的位置。

相关函数
#include 
/*    用来创建和访问一个消息队列
    key:  与其他的IPC机制一样,程序必须提供一个键来命名某个特定的消息队列
    msg: flg是一个权限标志,表示消息队列的访问权限,它与文件的访问权限一样
    返回值:返回一个以key命名的消息队列的标识符(非零整数),失败时返回-1.
*/
int msgget(key_t  key, int msgflg);
/*    用来把消息添加到消息队列中
    msgid:是由msgget函数返回的消息队列标识符。
    msg_ptr:msg_ptr是一个指向准备发送消息的指针
    msg_sz:是msg_ptr指向的消息的长度,注意是消息的长度,而不是整个结构体的长度,也就是说msg_sz是不包括长整型消息类型成员变量的长度。
    msgflg:用于控制当前消息队列满或队列消息到达系统范围的限制时将要发生的事情
    返回值: 成功,消息数据的一分副本将被放到消息队列中,并返回0,失败时返回-1
*/
int msgsnd(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg); 
/*用来从一个消息队列获取消息
    msgid:是由msgget函数返回的消息队列标识符。
    msg_ptr:msg_ptr是一个指向准备发送消息的指针
    msg_st: 同上
    msgtype:可以实现一种简单的接收优先级。如果msgtype为0,就获取队列中的第一个消息。如果它的值大于零,将获取具有相同消息类型的第一个信息。如果它小于零,就获取类型等于或小于msgtype的绝对值的第一个消息。
    msgflg:用于控制当队列中没有相应类型的消息可以接收时将发生的事情
    返回值: 成功时,该函数返回放到接收缓存区中的字节数,消息被复制到由msg_ptr指向的用户分配的缓存区中,然后删除消息队列中的对应消息。失败时返回-1.
*/
int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);
/*    用来控制消息队列,它与共享内存的shmctl函数相似
    msgid:是由msgget函数返回的消息队列标识符。
    Command:是将要采取的动作,它可以取3个值,
        IPC_STAT:把msgid_ds结构中的数据设置为消息队列的当前关联值,即用消息队列的当前关联值覆盖msgid_ds的值。
        IPC_SET:如果进程有足够的权限,就把消息列队的当前关联值设置为msgid_ds结构中给出的值
        IPC_RMID:删除消息队列
    buf:是指向msgid_ds结构的指针,它指向消息队列模式和访问权限的结构。msgid_ds结构至少包括以下成员:
        struct msgid_ds {  
            uid_t shm_perm.uid;  
            uid_t shm_perm.gid;  
            mode_t shm_perm.mode;  
        };
    返回值: 成功时返回0,失败时返回-1.
*/
int msgctl(int msgid, int command, struct msgid_ds *buf);
示例

client和server的通信

//comm.h
#ifndef _COMM_H_
#define _COMM_H_

#include 
#include 
#include 
#include 
#include 
#include 

struct msgbuf
{
    long mtype;
    char mtext[1024];
};

#define SERVER_TYPE 1
#define CLIENT_TYPE 2

int createMsgQueue();
int getMsgQueue();
int destoryMsgQueue(int msg_id);
int sendMsgQueue(int msg_id, int who, char* msg);
int recvMsgQueue(int msg_id, int recvType, char out[]);

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

static int commMsgQueue(int flags)
{
    key_t key = ftok("/tmp", 0x6666);
    if(key < 0)
    {
        perror("ftok");
        return -1;
    }

    int msg_id = msgget(key, flags);
    if(msg_id < 0)
    {
        perror("msgget");
    }
    return msg_id;
}

int createMsgQueue()
{
    return commMsgQueue(IPC_CREAT|IPC_EXCL|0666);
}

int getMsgQueue()
{
    return commMsgQueue(IPC_CREAT);
}

int destoryMsgQueue(int msg_id)
{
    if(msgctl(msg_id, IPC_RMID, NULL) < 0)
    {
        perror("msgctl");
        return -1;
    }
    return 0;
}

int sendMsgQueue(int msg_id, int who, char* msg)
{
    struct msgbuf buf;
    buf.mtype = who;
    strcpy(buf.mtext, msg);

    if(msgsnd(msg_id, (void*)&buf, sizeof(buf.mtext), 0) < 0)
    {
        perror("msgsnd");
        return -1;
    }
    return 0;
}

int recvMsgQueue(int msg_id, int recvType, char out[])
{
    struct msgbuf buf;
    int size=sizeof(buf.mtext);
    if(msgrcv(msg_id, (void*)&buf, size, recvType, 0) < 0)
    {
        perror("msgrcv");
        return -1;
    }

    strncpy(out, buf.mtext, size);
    out[size] = 0;
    return 0;
}
//server.c
#include "comm.h"

int main()
{
    int msgid = createMsgQueue();

    char buf[1024] = {0};
    while(1)
    {
        recvMsgQueue(msgid, CLIENT_TYPE, buf);
        if(strcasecmp("quit", buf) == 0)
            break;
        printf("client# %s
", buf);

        printf("Please enter# ");
        fflush(stdout);
        ssize_t s = read(0, buf, sizeof(buf));
        if(s>0)
        {
            buf[s-1]=0;
            sendMsgQueue(msgid, SERVER_TYPE, buf);
            printf("send done, wait recv...
");
        }
    }

    destoryMsgQueue(msgid);
    return 0;
}
//client.c
#include "comm.h"

int main()
{
    int msgid = getMsgQueue();

    char buf[1024] = {0};
    while(1)
    {
        printf("Please Enter# ");
        fflush(stdout);
        ssize_t s = read(0, buf, sizeof(buf));
        if(s > 0)
        {
            buf[s-1]=0;
            sendMsgQueue(msgid, CLIENT_TYPE, buf);
            if(strcasecmp("quit", buf) == 0)
                break;
            printf("send done, wait recv...
");
        }

        recvMsgQueue(msgid, SERVER_TYPE, buf);
        printf("server# %s
", buf);
    }
    return 0;
}

运行结果

root@jonathan-pc:~/test/msg# ls
client.c  comm.c  comm.h  server.c
root@jonathan-pc:~/test/msg# gcc client.c comm.c -o c
root@jonathan-pc:~/test/msg# gcc server.c comm.c -o s
root@jonathan-pc:~/test/msg# ./s
client# hello
Please enter# nihao
send done, wait recv...
root@jonathan-pc:~/test/msg#
root@jonathan-pc:~/test/msg# ./c
Please Enter# hello
send done, wait recv...
nihaoserver# nihao
Please Enter# quit
send done, wait recv...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/63197.html

相关文章

  • Linuxc - 进程间通信-XSI-IPC

    摘要:进程间通信有三种消息队列信号量共享存储器详情见环境高级编程小节命令查看删除某个函数标识符和键,每个结构都有一个非负整数的标识符。也用来使多个进程在同一上汇聚。创建一个可以是项目路径,或者其他 linuxc-进程间通信-XSI-IPC ​ 有三种:消息队列、信号量、共享存储器 ​ 详情见《unix环境高级编程》15.6小节 命令 ipcs:查看ipc ipcrm:删除某个ip...

    huangjinnan 评论0 收藏0
  • Linuxc - 信号量

    摘要:信号量信号灯,也叫信号量,它是不同进程间或一个给定进程内部不同线程间同步的机制。不同进程通过使用同一个信号键值来获得同一个信号量初始化信号量,此时使用函数的操作。当使用二维信号量时,通常将信号量初始化为进行信号量的操作,此时调用函数。 linuxc-信号量 ​ 信号灯(semaphore),也叫信号量,它是不同进程间或一个给定进程内部不同线程间同步的机制。 ​ 信号灯种类:...

    Kyxy 评论0 收藏0
  • Linuxc - syslog使用方法小结

    摘要:使用方法小结已被许多日志函数采纳,它用在许多保护措施中任何程序都可以通过纪录事件。该文件由不同程序或消息分类的单个条目组成,每个占一行。通常应广播到所有用户告警,当前状态必须立即进行纠正。所有已登录的用户都将收到信息。 syslog使用方法小结 Syslog已被许多日志函数采纳,它用在许多保护措施中——任何程序都可以通过syslog 纪录事件。Syslog可以纪录系统事件,可以写到一个...

    madthumb 评论0 收藏0
  • linuxc - linuxc串口操作

    摘要:如下的,分别表示的是串口和串口。忽略桢错误和奇偶校验错。如果既没有设置也没有设置,将有奇偶校验错或桢错误的字符视为。允许输出产生奇偶信息以及输入的奇偶校验启用同位产生与侦测。 linux串口操作 man termios:http://www.man7.org/linux/man... 串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用。常用的串口是RS-232-C接口...

    Jason 评论0 收藏0
  • Linuxc - 共享内存

    摘要:数据或代码页会根据需要在物理内存与磁盘之间移动。因此,采用共享内存的通信方式效率是最高的。必须控制同一时刻只有一个进程对共享内存区域写入数据,否则会造成数据的混乱。 linuxc-共享内存 ​ --详细概念见《unix环境高级编程》15.9小节 ​ 共享内存可以说是Linux 下最快速、最有效的进程间通信方式。两个不同进程A 、B 共享内存的意思是,同一块物理内存被映射到进...

    Jeffrrey 评论0 收藏0

发表评论

0条评论

lansheng228

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<