Zephyr 消息队列,带或不带信号量 + 奖励产生问题

Zephyr message queue with or without semaphore + bonus yielding question

提问人:Gambanishu Habbeba 提问时间:11/17/2023 更新时间:11/17/2023 访问量:11

问:

请考虑以下方案:从 UART 读取消息,然后在优先级较低的线程中解释它们。一种方法是创建一个包含 n 个项目的消息队列并添加传入行。同时给出一个信号量(最大值为 n)。优先级较低的线程将信号量和消息从队列中取出以对其进行处理:

K_MSGQ_DEFINE(uartRxMsgQ, uartFrameSize, uartMsgQSize, 4);
K_SEM_DEFINE(messageSemaphore, 0, uartMsgQSize);

static void uart_isr_handler(const struct device *dev, struct uart_event *event, void *user_data) {
    switch (event->type) {
        case UART_RX_RDY:
            for (size_t n = event->data.rx.offset; n < event->data.rx.offset + event->data.rx.len; n++) {
                if (*(event->data.rx.buf + n) == '\n' || *(event->data.rx.buf + n) == '\r') {
                    if (uartFramePos > 0) {
                        uartFrameBuff[uartFramePos] = 0;

                        if (k_msgq_put(&uartRxMsgQ, &uartFrameBuff, K_NO_WAIT) == 0) 
                            k_sem_give(&messageSemaphore);
                        else
                            LOG_ERR("Uart RX message queue full");

                        uartFramePos = 0;
                    }
                } else if (uartFramePos < uartFrameSize - 1) uartFrameBuff[uartFramePos++] = event->data.rx.buf[n];
            }
            break;
    }
}

void msg_processor_thread() {
    static uint8_t incomingMsg[uartFrameSize];

    while (1) {
        k_sem_take(&messageSemaphore, K_FOREVER);
        k_msgq_get(&uartRxMsgQ, &incomingMsg, K_FOREVER);
        LOG_INF("RX: %s", incomingMsg);
    }
}

因此,如果信号量指示队列中的消息数。如果队列是空的,take will block,线程是快乐的。uartMsgQSize = 10;

但是呢?对于这个具体的例子,它不会像尝试获取信号量一样阻塞吗?在这种情况下,使用信号量有什么好处吗?除了管理信号量的开销之外,还有区别吗?k_msgq_get(&uartRxMsgQ, &incomingMsg, K_FOREVER);

奖励问题:while 循环是否需要让步?我对这种情况的解释是,如果没有产量,这个线程可能会使所有其他线程挨饿,直到它处理完队列中的所有消息。一旦它变得活跃,它将处理所有消息,直到它不能再接受信号量。甚至更高优先级的线程也会受到影响,对吗?在循环中产生产量时,它只会发生在优先级较低的线程上,对吗?所以如果我写:msg_processor_thread()

while (1) {
        k_sem_take(&messageSemaphore, K_FOREVER);
        k_msgq_get(&uartRxMsgQ, &incomingMsg, K_FOREVER);
        LOG_INF("RX: %s", incomingMsg);
        k_yield();
    }

在每条消息之后,调度程序将有机会切换到更重要的事情。所以我的猜测是,收益率更有意义。我看对了吗?

C 多线程 信号量 Zephyr-RTOS

评论


答: 暂无答案