首页 > 代码库 > Linux 进程间通讯详解二

Linux 进程间通讯详解二

消息队列
--消息队列提供了本机上从一个进程向另外一个进程发送一块数据的方法
--每个数据块都被认为有一个类型,接收者进程接收的数据块可以有不同的类型值
--消息队列也有管道一样的不足,就是每个消息的最大长度是由上限的(MSGMAX),每个消息队列的总的字节数是有上限的(MSGMNB),系统上消息队列的总数也有一个上限(MSGMNI)
消息大小的三大限制
cat /proc/sys/kernel/msgmax --最大消息的长度限制(65536)
cat /proc/sys/kernel/msgmnb --消息队列总的字节数(65536)
cat /proc/sys/kernel/msgmni --消息队列的条目数(1465)
删除消息队列命令
--ipcrm msg msqid (注意是msg不是msq)
--ipcrm -q msqid
--注意:当msqid大于0时,这两个命令都可以释放消息队列,但是当msqid=0时(msqid=0这种情况很罕见),ipcrm msg msqid会报错
megget()函数
int msgget(key_t key, int msgflg);
--功能:用来创建和访问一个消息队列
--参数
    key    某个消息队列的名字
    msgflg    由九个权限标志构成,他们的用法和创建文件时使用的model模式标志是一样的
              详解:这实际上是一个字变量,int类型有32位,前面9位用来标识读写权限(rwxr--r----成功返回一个非负整数,失败返回-1,并且更新errno
//消息队列
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int main(int arg, char * args[])
{
    /*以可读可写方式打开消息队列,文件必须要存在,如果消息队列不存在,errno=ENOENT*/
    //int msgid=msgget(0x1234,0666);
    /*如果消息队列存在,使用现有消息队列,不存在该key值的消息队列,创建消息队列*/
    //int msgid=msgget(0x1234,0666|IPC_CREAT);
    /*如果没有该key值的消息队列,则创建消息队列,如果存在该消息队列,则报错提示文件已存在
     * 一般用于判断消息队列是否存在(防止用户使用该key值的消息队列的新内容覆盖原有内容)
     * IPC_EXCL单独使用没有效果,必须和IPC_CREAT一起使用
     * */
    //int msgid = msgget(0x1234, 0666 | IPC_CREAT | IPC_EXCL);
    /*IPC_PRIVATE创建的消息队列只供父子进程间使用
     * 每次使用IPC_PRIVATE都会创建一个新的消息队列,不会使用原来的,
     * 因为使用IPC_PRIVATE不再具有访问现有消息队列的功能
     * 所以IPC_CREAT和IPC_EXCL都没有用
     * 但是在父子进程间,因为程序还没有结束,所以父进程仍然在使用消息队列,
     * 所以子进程也可以用该消息队列与父进程交互信息
     * IPC_PRIVATE 宏  值是0
     * */
    int msgid = msgget(IPC_PRIVATE, 0666);
    if (msgid == -1)
    {
        if (errno == ENOENT)
        {
            printf("自定义错误:没有该文件!\n");
            return -1;
        }
        if (errno == EEXIST)
        {
            printf("自定义错误:该消息队列已经存在!\n");
            return -1;
        }
        perror("msgget() err");
        return -1;
    }
    printf("创建消息队列成功!id=%d \n", msgid);
    return 0;
}

 

//消息队列
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int main(int arg, char * args[])
{
    //如果有,使用现有的,没有,创建一个
    int msgid = msgget(0x1234, 0444 | IPC_CREAT);
    if (msgid == -1)
    {
        perror("msgget() err");
        return -1;
    }
    //以可读可写的权限访问一个只读不可写的消息队列 报错
    msgid = msgget(0x1234, 0666);
    if (msgid == -1)
    {
        perror("msgget() err");
        return -1;
    }
    return 0;
}

 

Linux 进程间通讯详解二