MST

星途 面试题库

面试题:C语言在Linux消息队列中如何处理消息的发送与接收

在Linux环境下使用C语言操作消息队列,描述一下消息发送函数msgsnd和消息接收函数msgrcv的基本参数及其作用,并且说明在发送和接收消息过程中可能会遇到哪些常见错误,如何处理这些错误?
33.3万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

msgsnd函数

  1. 基本参数及其作用

    • int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
      • msqid:消息队列标识符,由msgget函数返回,用于指定要发送消息的消息队列。
      • msgp:指向要发送的消息结构体的指针。该结构体一般定义如下:
        struct msgbuf {
            long mtype; /* 消息类型,必须大于0 */
            char mtext[1]; /* 消息正文,实际长度由msgsz指定 */
        };
        
      • msgszmsgp指向的消息正文(不包括mtype字段)的字节数。
      • msgflg:标志位,常用值有:
        • IPC_NOWAIT:若消息队列已满,不等待,立即返回EAGAIN错误。
        • 0:若无可用空间,进程阻塞直到有空间或队列被删除。
  2. 常见错误及处理

    • EACCES:权限不足。检查消息队列的权限设置,确保当前进程有发送消息的权限。可以通过ipcs -q查看消息队列权限,必要时修改权限(如使用ipcrm -q msqid删除队列后重新创建并设置合适权限)。
    • EAGAIN:当设置了IPC_NOWAIT且消息队列已满时返回。可以选择等待一段时间后重试,或者调整消息队列大小(通过ipcs -l查看系统限制,通过修改内核参数等方式调整)。
    • EFAULTmsgp指针指向的地址非法。检查msgp指针是否正确分配内存。
    • EIDRM:消息队列已被删除。重新获取消息队列标识符(通过msgget)并重新发送。
    • EINVALmsqid无效,或者msgsz超过系统限制(MSGMAX)。检查msqid是否正确获取,调整msgsz大小在系统允许范围内(可通过sysctl -a | grep msgmax查看MSGMAX值)。

msgrcv函数

  1. 基本参数及其作用

    • ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
      • msqid:消息队列标识符,同msgsnd,指定要接收消息的消息队列。
      • msgp:指向用于接收消息的结构体的指针,结构体定义与发送时类似。
      • msgszmsgp指向的消息正文(不包括mtype字段)的最大字节数。实际接收的字节数会返回。
      • msgtyp:指定要接收的消息类型:
        • msgtyp == 0:接收消息队列中的第一条消息。
        • msgtyp > 0:接收消息类型为msgtyp的第一条消息。
        • msgtyp < 0:接收消息类型小于等于abs(msgtyp)的消息中类型最小的第一条消息。
      • msgflg:标志位,常用值有:
        • IPC_NOWAIT:若没有符合条件的消息,不等待,立即返回ENOMSG错误。
        • MSG_NOERROR:若消息正文长度大于msgsz,截断消息正文,不返回错误。
  2. 常见错误及处理

    • E2BIG:消息正文长度大于msgsz且未设置MSG_NOERROR。可以增大msgsz,或者处理截断后的消息(若设置了MSG_NOERROR)。
    • EACCES:权限不足。处理方式同msgsnd中的EACCES错误,检查和调整消息队列权限。
    • EAGAIN:设置了IPC_NOWAIT且无符合条件的消息。可以等待一段时间后重试。
    • EFAULTmsgp指针指向的地址非法。检查msgp指针是否正确分配内存。
    • EIDRM:消息队列已被删除。重新获取消息队列标识符(通过msgget)并重新接收。
    • EINVALmsqid无效,或者msgsz小于0。检查msqid是否正确获取,确保msgsz为非负。
    • ENOMSG:设置了IPC_NOWAIT且无符合条件的消息。处理方式同EAGAIN,等待后重试。