菜单

Cobalt/Message queues

详细描述

Cobalt/POSIX 消息队列服务。

消息队列允许实时线程之间交换数据。对于 POSIX 消息队列,最大消息长度和最大消息数量在使用 mq_open() 创建时被固定。


函数文档

mq_timedsend()

int mq_timedsend(mqd_t mqdes, const char *msg_ptr,
size_t msg_len, unsigned int msg_prio,
const struct timespec *abs_timeout);

在限定时间内尝试向消息队列发送消息。

该服务等同于 mq_send(),不同之处在于如果消息队列已满且描述符 fd 未设置 O_NONBLOCK 标志,则调用线程仅在指定的 abs_timeout 超时时间到期前被挂起。

参数:

  • mqdes: 消息队列描述符;
  • msg_ptr: 指向要发送的消息的指针;
  • msg_len: 消息的长度;
  • msg_prio: 消息的优先级;
  • abs_timeout: 超时时间,以 CLOCK_REALTIME 时钟的绝对值表示。

返回值:

  • 成功时返回 0 并发送消息;
  • 失败时返回 -1,未发送消息并设置 errno
    • EBADFfd 不是一个有效的用于写入的消息队列描述符;
    • EMSGSIZE,消息长度超过消息队列的 mq_msgsize 属性;
    • EAGAIN,描述符 fd 设置了 O_NONBLOCK 标志且消息队列已满;
    • EPERM,调用者上下文无效;
    • ETIMEDOUT,指定的超时时间已到期;
    • EINTR,服务被信号中断。

标签:

  • xthread-onlyswitch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <errno.h>

int main() {
    mqd_t mq;
    struct mq_attr attr;
    char *message = "Hello, World!";
    struct timespec timeout;

    // 设置消息队列的属性
    attr.mq_flags = 0;
    attr.mq_maxmsg = 10;
    attr.mq_msgsize = 128;
    attr.mq_curmsgs = 0;

    // 创建或打开消息队列
    mq = mq_open("/my_queue", O_CREAT | O_WRONLY, 0644, &attr);
    if (mq == (mqd_t)-1) {
        perror("mq_open");
        exit(1);
    }

    // 设置超时时间,例如5秒
    timeout.tv_sec = 5;
    timeout.tv_nsec = 0;

    // 发送消息,设置超时时间
    if (mq_timedsend(mq, message, strlen(message) + 1, 1, &timeout) == -1) {
        if (errno == ETIMEDOUT) {
            perror("Message send timed out");
        } else {
            perror("mq_timedsend");
        }
        mq_close(mq);
        exit(1);
    }

    printf("Message sent\n");

    // 关闭消息队列
    mq_close(mq);

    return 0;
}

mq_timedreceive()

ssize_t mq_timedreceive(mqd_t q, char *buffer,
size_t len, unsigned int *prio,
const struct timespec *timeout);

在限定时间内尝试从消息队列接收消息。

该服务等同于 mq_receive(),不同之处在于如果描述符 fd 未设置 O_NONBLOCK 标志且消息队列为空,则调用线程仅在指定的 abs_timeout 超时时间到期前被挂起。

参数:

  • q: 队列描述符;
  • buffer: 成功时用于存储接收消息的地址;
  • len: 缓冲区长度;
  • prio: 成功时用于存储接收消息优先级的地址;
  • timeout: 超时时间,以 CLOCK_REALTIME 时钟的绝对值表示。

返回值:

  • 成功时返回消息长度,并将消息复制到 buffer 地址;
  • 失败时返回 -1,未出队消息并设置 errno
    • EBADFfd 不是一个有效的用于读取的描述符;
    • EMSGSIZE,长度 len 小于消息队列的 mq_msgsize 属性;
    • EAGAIN,队列为空,且描述符 fd 设置了 O_NONBLOCK 标志;
    • EPERM,调用者上下文无效;
    • EINTR,服务被信号中断;
    • ETIMEDOUT,指定的超时时间已到期。

标签:

  • xthread-onlyswitch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <errno.h>

int main() {
    mqd_t mq;
    struct mq_attr attr;
    char buffer[128];
    unsigned int priority;
    struct timespec timeout;
    unsigned int max_cycles = 10;

    // 设置消息队列的属性
    attr.mq_flags = 0;      // 消息队列标志
    attr.mq_maxmsg = 10;    // 最大消息数
    attr.mq_msgsize = 128;  // 最大消息大小
    attr.mq_curmsgs = 0;    // 当前消息数

    // 创建或打开消息队列
    mq = mq_open("/my_queue", O_CREAT | O_RDONLY, 0644, &attr);
    if (mq == (mqd_t)-1) {
        perror("mq_open");
        exit(1);
    }

    // 设置超时时间,例如5秒
    timeout.tv_sec = 5;
    timeout.tv_nsec = 0;

    for (int i = 0; i < max_cycles; i++) {
        // 接收消息,设置超时时间
        ssize_t bytes_received = mq_timedreceive(mq, buffer, sizeof(buffer), &priority, &timeout);
        if (bytes_received == -1) {
            if (errno == ETIMEDOUT) {
                perror("Message receive timed out");
            } else {
                perror("mq_timedreceive");
                mq_close(mq);
                exit(1);
            }
            
        }
        // 打印接收到的消息
        buffer[bytes_received] = '\0'; // 确保字符串以NULL结尾
        printf("Received message[%d]: %s\n", priority, buffer);
    }
    // 关闭消息队列
    mq_close(mq);

    return 0;
}

mq_close()

int mq_close(mqd_t mqd)

关闭消息队列。

该服务关闭消息队列描述符 mqd。消息队列仅在所有打开的描述符都关闭并通过调用 mq_unlink() 服务取消链接后才会被销毁。

参数:

  • mqd: 消息队列描述符。

返回值:

  • 成功时返回 0
  • 失败时返回 -1 并设置 errno
    • EBADFmqd 是无效的消息队列描述符;
    • EPERM,调用者上下文无效。

标签:

  • thread-unrestrictedswitch-secondary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <errno.h>

int main() {
    mqd_t mq;
    struct mq_attr attr;
    char *message = "Hello, World!";
    struct timespec timeout;

    // 设置消息队列的属性
    attr.mq_flags = 0;      // 消息队列标志
    attr.mq_maxmsg = 10;    // 最大消息数
    attr.mq_msgsize = 128;  // 最大消息大小
    attr.mq_curmsgs = 0;    // 当前消息数

    // 创建或打开消息队列
    mq = mq_open("/my_queue", O_CREAT | O_WRONLY, 0644, &attr);
    if (mq == (mqd_t)-1) {
        perror("mq_open");
        exit(1);
    }

    // 设置超时时间,例如5秒
    timeout.tv_sec = 5;
    timeout.tv_nsec = 0;

    // 发送消息,设置超时时间
    if (mq_timedsend(mq, message, strlen(message) + 1, 1, &timeout) == -1) {
        if (errno == ETIMEDOUT) {
            perror("Message send timed out");
        } else {
            perror("mq_timedsend");
        }
        mq_close(mq);
        exit(1);
    }

    printf("Message sent\n");

    // 关闭消息队列
    mq_close(mq);

    return 0;
}

mq_getattr()

int mq_getattr(mqd_t mqd, struct mq_attr *attr)

获取消息队列属性。

该服务将消息队列描述符 mqd 的属性存储在 attr 指定的地址。

以下属性将被设置:

  • mq_flags: 消息队列描述符 mqd 的标志;
  • mq_maxmsg: 消息队列中的最大消息数;
  • mq_msgsize: 最大消息大小;
  • mq_curmsgs: 当前队列中的消息数。

参数:

  • mqd: 消息队列描述符;
  • attr: 成功时用于存储消息队列属性的地址。

返回值:

  • 成功时返回 0
  • 失败时返回 -1 并设置 errno
    • EBADFmqd 不是一个有效的描述符。

标签:

  • thread-unrestricted

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>

int main() {
    mqd_t mq;
    struct mq_attr attr, newattr;

    // 设置消息队列的属性
    attr.mq_flags = 0;      // 消息队列标志
    attr.mq_maxmsg = 10;    // 最大消息数
    attr.mq_msgsize = 128;  // 最大消息大小
    attr.mq_curmsgs = 0;    // 当前消息数

    // 打开消息队列,如果不存在则创建
    mq = mq_open("/my_queue", O_CREAT | O_RDWR, 0644, &attr);
    if (mq == (mqd_t)-1) {
        perror("mq_open");
        exit(1);
    }

    // 获取当前的消息队列属性
    if (mq_getattr(mq, &newattr) == -1) {
        perror("mq_getattr");
        mq_close(mq);
        exit(1);
    }

    // 打印当前属性
    printf("Current message queue attributes:\n");
    printf("  mq_flags: %d\n", attr.mq_flags);
    printf("  mq_maxmsg: %lu\n", attr.mq_maxmsg);
    printf("  mq_msgsize: %lu\n", attr.mq_msgsize);
    printf("  mq_curmsgs: %lu\n", attr.mq_curmsgs);

    // 关闭消息队列
    if (mq_close(mq) == -1) {
        perror("mq_close");
        exit(1);
    }

    // 删除消息队列
    if (mq_unlink("/my_queue") == -1) {
        perror("mq_unlink");
        exit(1);
    }

    return 0;
}

mq_notify()

int mq_notify(mqd_t mqd, const struct sigevent *evp)

启用消息到达通知。

如果 evp 不是 NULL 且是一个 sigevent 结构体的地址,并且其 sigev_notify 成员设置为 SIGEV_SIGNAL,当消息发送到消息队列 mqd 时,如果队列为空且没有线程阻塞在 mq_receive()mq_timedreceive() 调用中,当前线程将通过信号通知。通知后,线程将被注销。

如果 evpNULLsigev_notify 成员为 SIGEV_NONE,当前线程将被注销。

一次只能注册一个线程。

如果当前线程不是 Cobalt 线程(通过 pthread_create() 创建),此服务将失败。

参数:

  • mqd: 消息队列描述符;
  • evp: 指向事件通知结构的指针。

返回值:

  • 成功时返回 0
  • 失败时返回 -1 并设置 errno
    • EINVALevp 无效;
    • EPERM:调用者上下文无效;
    • EBADFmqd 不是有效的消息队列描述符;
    • EBUSY:另一个线程已注册。

标签:

  • xthread-onlyswitch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <mqueue.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>

#define QUEUE_NAME "/my_queue"
#define MAX_MSG_SIZE 1024
#define QUEUE_PERMISSIONS 0660
int get_new_msg = 0;
void notify_fun(union sigval sv){
    printf("Get Notify Message\n");
    get_new_msg++;
}

void *receiver(void *arg) 
{
    mqd_t mq = *((mqd_t *)arg);
    int read_msg = get_new_msg;
    struct sigevent sev;
    sev.sigev_notify = SIGEV_THREAD;
    sev.sigev_notify_function = notify_fun;
    sev.sigev_value.sival_ptr = &mq;
    if(mq_notify(mq, &sev) == -1){
        perror("mq_notify");
        mq_close(mq);
        mq_unlink(QUEUE_NAME);
        exit(1);
    }
    char buffer[MAX_MSG_SIZE];
    while(1){
        if(get_new_msg > read_msg){
             ssize_t bytes_read = mq_receive(mq, buffer, MAX_MSG_SIZE, NULL);
            if (bytes_read >= 0) {
                buffer[bytes_read] = '\0';
                printf("Received: %s\n", buffer);
                mq_notify(mq, &sev);  // Re-register notification
            } else {
                perror("mq_receive");
            }
            read_msg++;
        }
        usleep(1000);
    }
    return NULL;
}

int main() {
    struct mq_attr attr;
    attr.mq_flags = 0;      // 消息队列标志
    attr.mq_maxmsg = 10;    // 最大消息数
    attr.mq_msgsize = 128;  // 最大消息大小
    attr.mq_curmsgs = 0;    // 当前消息数

    mqd_t mq = mq_open(QUEUE_NAME, O_CREAT | O_RDWR, 0664, &attr);
    if (mq == (mqd_t)-1) {
        perror("mq_open");
        exit(1);
    }
    
    pthread_t tid;
    pthread_create(&tid, NULL, receiver, &mq);
    usleep(100*1000);
    char *messages[] = {"Hello", "World", "Goodbye"};
    for (int i = 0; i < 3; i++) {
        mq_send(mq, messages[i], strlen(messages[i]) + 1, 0);
        sleep(1);
    }
    pthread_cancel(tid);
    mq_close(mq);
    mq_unlink(QUEUE_NAME);
    return 0;
}

mq_open()

mqd_t mq_open (const char* name, int oflags, ...)

打开消息队列。

该服务打开名为 name 的消息队列。

oflags 应设置为以下值之一:

  • O_RDONLY:表示返回的队列描述符只能用于接收消息;
  • O_WRONLY:表示返回的队列描述符只能用于发送消息;
  • O_RDWR:表示返回的队列描述符可用于发送和接收消息。

如果不存在名为 name 的消息队列,并且 oflags 设置了 O_CREAT 位,则该函数会创建消息队列,并接受另外两个参数:

  1. 一个 mode 参数,类型为 mode_t,当前被忽略;
  2. 一个 attr 参数,指向 mq_attr 结构体的指针,指定新消息队列的属性。

如果 oflags 设置了 O_CREATO_EXCL 两个位,并且消息队列已经存在,则该服务会失败。

如果 oflags 设置了 O_NONBLOCK 位,则 mq_send()mq_receive()mq_timedsend()mq_timedreceive() 服务会返回 -1 并将 errno 设置为 EAGAIN,而不是阻塞调用者。

在创建消息队列时,会使用 attr 地址处的 mq_attr 结构体的以下参数:

  • mq_maxmsg:队列中的最大消息数(默认128);
  • mq_msgsize:每条消息的最大大小(默认128)。

name 可以是任意字符串,其中斜杠没有特别意义。然而,为了便于移植,建议使用以斜杠开头且不包含其他斜杠的名称。

参数:

  • name:要打开的消息队列的名称;
  • oflags:标志。

返回值:
成功时返回消息队列描述符;
失败时返回 -1 并设置 errno

  • ENAMETOOLONGname 参数的长度超过64个字符;
  • EXISToflags 中设置了 O_CREATO_EXCL 位,并且消息队列已经存在;
  • ENOENToflags 中未设置 O_CREAT 位,并且消息队列不存在;
  • ENOSPC:系统内存分配失败,或系统堆中可用内存不足以创建队列,请尝试增加 CONFIG_XENO_OPT_SYS_HEAPSZ
  • EPERM:尝试从无效上下文创建消息队列;
  • EINVALattr 参数无效;
  • EMFILE:当前打开的描述符过多;
  • EAGAIN:没有可用的注册槽,请检查/增加 CONFIG_XENO_OPT_REGISTRY_NRSLOTS

标签:

  • thread-unrestrictedswitch-secondary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <errno.h>

int main() {
    mqd_t mq;
    struct mq_attr attr;
    char *message = "Hello, World!";
    struct timespec timeout;

    // 设置消息队列的属性
    attr.mq_flags = 0;      // 消息队列标志
    attr.mq_maxmsg = 10;    // 最大消息数
    attr.mq_msgsize = 128;  // 最大消息大小
    attr.mq_curmsgs = 0;    // 当前消息数

    // 创建或打开消息队列
    mq = mq_open("/my_queue", O_CREAT | O_WRONLY, 0644, &attr);
    if (mq == (mqd_t)-1) {
        perror("mq_open");
        exit(1);
    }

    // 设置超时时间,例如5秒
    timeout.tv_sec = 5;
    timeout.tv_nsec = 0;

    // 发送消息,设置超时时间
    if (mq_timedsend(mq, message, strlen(message) + 1, 1, &timeout) == -1) {
        if (errno == ETIMEDOUT) {
            perror("Message send timed out");
        } else {
            perror("mq_timedsend");
        }
        mq_close(mq);
        exit(1);
    }

    printf("Message sent\n");

    // 关闭消息队列
    mq_close(mq);

    return 0;
}

mq_receive()

ssize_t mq_receive (mqd_t q, char* buffer, size_t len, unsigned* prio)

从消息队列接收消息。

如果消息队列 fd 不为空,并且 len 大于消息队列的 mq_msgsize,该服务会将优先级最高的排队消息复制到 buffer 地址。

如果队列为空且描述符 fd 未设置 O_NONBLOCK 标志,调用线程将被挂起,直到有消息发送到队列。如果队列为空且描述符 fd 设置了 O_NONBLOCK 标志,该服务会立即返回 -1 并将 errno 设置为 EAGAIN

参数:

  • q: 队列描述符;
  • buffer: 成功时用于存储接收消息的地址;
  • len: 缓冲区长度;
  • prio: 成功时用于存储接收消息优先级的地址。

返回值:
成功时返回消息长度,并将消息复制到 buffer 地址;
失败时返回 -1,未出队消息并设置 errno
- EBADFfd 不是一个有效的用于读取的描述符;
- EMSGSIZE:长度 len 小于消息队列的 mq_msgsize 属性;
- EAGAIN:队列为空,且描述符 fd 设置了 O_NONBLOCK 标志;
- EPERM:调用者上下文无效;
- EINTR:服务被信号中断。

标签:

  • xthread-onlyswitch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <errno.h>

int main() {
    mqd_t mq;
    struct mq_attr attr;
    char buffer[128];
    unsigned int priority;
    unsigned int max_cycles = 10;

    // 设置消息队列的属性
    attr.mq_flags = 0;      // 消息队列标志
    attr.mq_maxmsg = 10;    // 最大消息数
    attr.mq_msgsize = 128;  // 最大消息大小
    attr.mq_curmsgs = 0;    // 当前消息数

    // 创建或打开消息队列
    mq = mq_open("/my_queue", O_CREAT | O_RDONLY, 0644, &attr);
    if (mq == (mqd_t)-1) {
        perror("mq_open");
        exit(1);
    }
    for(int i = 0; i < max_cycles; i++) {
        // 接收消息
        ssize_t bytes_received = mq_receive(mq, buffer, sizeof(buffer), &priority);
        if (bytes_received == -1) {
            perror("mq_timedreceive");
            mq_close(mq);
            exit(1);
        }

        // 打印接收到的消息
        buffer[bytes_received] = '\0'; // 确保字符串以NULL结尾
        printf("Received message[%d]: %s\n", priority, buffer);
    }
    // 关闭消息队列
    mq_close(mq);

    return 0;
}

mq_send()

int mq_send (mqd_t q, const char* buffer, size_t len, unsigned prio)

发送消息到消息队列。

如果消息队列 fd 未满,该服务会发送由参数 buffer 指向的长度为 len 的消息,并设置优先级 prio。优先级较高的消息会插入到优先级较低的消息之前。

如果消息队列已满且未设置 O_NONBLOCK 标志,调用线程将被挂起,直到队列不满。如果消息队列已满且设置了 O_NONBLOCK 标志,消息不会被发送,服务会立即返回 -1 并将 errno 设置为 EAGAIN

参数:

  • q: 消息队列描述符;
  • buffer: 指向要发送的消息的指针;
  • len: 消息长度;
  • prio: 消息的优先级。

返回值:
成功时返回 0 并发送消息;
失败时返回 -1 并未发送消息,同时设置 errno

  • EBADFfd 不是一个有效的用于写入的消息队列描述符;
  • EMSGSIZE:消息长度 len 超过消息队列的 mq_msgsize 属性;
  • EAGAIN:描述符 fd 设置了 O_NONBLOCK 标志且消息队列已满;
  • EPERM:调用者上下文无效;
  • EINTR:服务被信号中断。

标签:

  • xthread-onlyswitch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <errno.h>

int main() {
    mqd_t mq;
    struct mq_attr attr;
    char *message = "Hello, World!";

    // 设置消息队列的属性
    attr.mq_flags = 0;      // 消息队列标志
    attr.mq_maxmsg = 10;    // 最大消息数
    attr.mq_msgsize = 128;  // 最大消息大小
    attr.mq_curmsgs = 0;    // 当前消息数

    // 创建或打开消息队列
    mq = mq_open("/my_queue", O_CREAT | O_WRONLY, 0644, &attr);
    if (mq == (mqd_t)-1) {
        perror("mq_open");
        exit(1);
    }

    // 发送消息
    if (mq_send(mq, message, strlen(message) + 1, 1) == -1) {
        perror("mq_send");
        mq_close(mq);
        exit(1);
    }

    printf("Message sent\n");

    // 关闭消息队列
    mq_close(mq);

    return 0;
}

mq_setattr()

int mq_setattr (mqd_t mqd, const struct mq_attr *restrict attr, struct mq_attr *restrict oattr)

设置消息队列属性。

该服务将 mqd 描述符的标志设置为 attr 指向的 mq_attr 结构体的 mq_flags 成员的值。

如果 oattr 不为 NULL,则先前的消息队列属性值将存储在 oattr 指定的地址。

只有设置或清除 O_NONBLOCK 标志才会生效。

参数:

  • mqd: 消息队列描述符;
  • attr: 指向新属性的指针(仅使用 mq_flags);
  • oattr: 如果不为 NULL,成功时用于存储先前消息队列属性的地址。

返回值:

  • 成功时返回 0
  • 失败时返回 -1 并设置 errno
    • EBADFmqd 不是有效的消息队列描述符。

标签:

  • thread-unrestricted

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>

int main() {
    mqd_t mq;
    struct mq_attr attr, oattr ,newattr;

    // 设置消息队列的属性
    attr.mq_flags = 0;      // 消息队列标志
    attr.mq_maxmsg = 10;    // 最大消息数
    attr.mq_msgsize = 128;  // 最大消息大小
    attr.mq_curmsgs = 0;    // 当前消息数

    // 打开消息队列,如果不存在则创建
    mq = mq_open("/my_queue", O_CREAT | O_RDWR, 0644, &attr);
    if (mq == (mqd_t)-1) {
        perror("mq_open");
        exit(1);
    }

    // 获取当前的消息队列属性
    if (mq_getattr(mq, &attr) == -1) {
        perror("mq_getattr");
        mq_close(mq);
        exit(1);
    }

    // 打印当前flag
    printf("Current message queue:  mq_flags: %ld\n", attr.mq_flags);

    // 修改消息队列属性
    attr.mq_flags = attr.mq_flags | O_NONBLOCK;

    // 设置消息队列属性
    if (mq_setattr(mq, &attr, &oattr) == -1) {
        perror("mq_setattr");
        mq_close(mq);
        exit(1);
    }

    if (mq_getattr(mq, &newattr) == -1) {
        perror("mq_getattr");
        mq_close(mq);
        exit(1);
    }
    // 打印修改后的属性
    printf("Updated message queue :  mq_flags: %ld\n", newattr.mq_flags);

    // 关闭消息队列
    if (mq_close(mq) == -1) {
        perror("mq_close");
        exit(1);
    }

    // 删除消息队列
    if (mq_unlink("/my_queue") == -1) {
        perror("mq_unlink");
        exit(1);
    }

    return 0;
}

mq_unlink()

int mq_unlink (const char * name)

取消链接消息队列。

该服务取消链接名为 name 的消息队列。消息队列在使用 mq_open() 服务获得的所有队列描述符通过 mq_close() 服务关闭之前不会被销毁。然而,调用该服务后,取消链接的队列将无法通过 mq_open() 服务访问。

参数:

  • name: 要取消链接的消息队列的名称。

返回值:

  • 成功时返回 0
  • 失败时返回 -1 并设置 errno
    • EPERM:调用者上下文无效;
    • ENAMETOOLONGname 参数的长度超过 64 个字符;
    • ENOENT:消息队列不存在。

标签:

  • thread-unrestrictedswitch-secondary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <errno.h>

int main() {
    mqd_t mq;
    struct mq_attr attr;
    char *message = "Hello, World!";

    // 设置消息队列的属性
    attr.mq_flags = 0;      // 消息队列标志
    attr.mq_maxmsg = 10;    // 最大消息数
    attr.mq_msgsize = 128;  // 最大消息大小
    attr.mq_curmsgs = 0;    // 当前消息数

    // 创建或打开消息队列
    mq = mq_open("/my_queue", O_CREAT | O_WRONLY, 0644, &attr);
    if (mq == (mqd_t)-1) {
        perror("mq_open");
        exit(1);
    }

    // 发送消息
    if (mq_send(mq, message, strlen(message) + 1, 1) == -1) {
        perror("mq_send");
        mq_close(mq);
        exit(1);
    }

    printf("Message sent\n");

    // 关闭消息队列
    mq_close(mq);
    if (mq_unlink("/my_queue") == -1) {
        perror("mq_unlink");
        exit(1);
    }
    return 0;
}
最近修改: 2025-07-24