summer_f 发表于 2024-3-12 12:22:16

关于队列先入先出的一点疑问

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include"freertos/queue.h"

void SendTask1(void *pvParam){
    QueueHandle_t QHandle;
    QHandle = (QueueHandle_t)pvParam;

    BaseType_t xStatus;
    int i=111;
    while (1){
      xStatus = xQueueSend(QHandle, &i, 0);
      if (xStatus != pdPASS)
      {
            printf(" Fail,Queue is FULL,Reset!.\n");
            xQueueReset(QHandle);
      }
      else
      {
             printf(" Success,Have [    %d] Loca.\n" ,uxQueueSpacesAvailable(QHandle));
      }
      vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}
void SendTask2(void *pvParam){
    QueueHandle_t QHandle;
    QHandle = (QueueHandle_t)pvParam;

    BaseType_t xStatus;
    int i=222;
    while (1){
      xStatus = xQueueSend(QHandle, &i, 0);
      
      if (xStatus != pdPASS)
      {
            printf(",Queue is FULL,Reset!.\n");
            xQueueReset(QHandle);
      }
      else
      {
            printf(" Success Have [    %d] Loca.\n" ,uxQueueSpacesAvailable(QHandle));
      }
      vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}
void ReceiveTask(void *pvParam){
    QueueHandle_t QHandle;
    QHandle = (QueueHandle_t)pvParam;

    BaseType_t xStatus;
    int j = 0;
    while (1)
    {
            xStatus = xQueueReceive(QHandle, &j, 0);

            if (xStatus != pdPASS){
                printf("Receive Fail.\n");
            }
            else{
                printf("*******************************\n");
                printf("Receive Success.i = <%d>.\n", j);
                printf("队列可用消息 = %d.\n", uxQueueMessagesWaiting(QHandle));
                printf("*******************************\n");
            }
      vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void app_main(void)
{
    QueueHandle_t QHandle;
    QHandle = xQueueCreate(5, sizeof(int));

    if (QHandle != NULL)
    {
      printf("Creat queue Successfully.\n");
      xTaskCreate(SendTask1, "SendTask1", 1024 * 5, (void *)QHandle, 1, NULL);
      xTaskCreate(SendTask2, "SendTask2", 1024 * 5, (void *)QHandle, 1, NULL);
      xTaskCreate(ReceiveTask, "ReceiveTask", 1024 * 5, (void *)QHandle, 3, NULL);
    }
    else{
      printf("Not Creat.\n");
    }
}
/*TAsk1和TASk2公用一个队列,后创建的先运行,循环发送数据,待队列满进行重启,始终都是TASK1重启
*/
终端显示:

Success Have [    4] Loca.
Success,Have [    3] Loca.
*******************************
Receive Success.i = <222>.
队列可用消息 = 1.
*******************************
Success Have [    3] Loca.
Success,Have [    2] Loca.
*******************************
Receive Success.i = <111>.
队列可用消息 = 2.
*******************************
Success Have [    2] Loca.
Success,Have [    1] Loca.
*******************************
Receive Success.i = <222>.
队列可用消息 = 3.
*******************************
Success Have [    1] Loca.
Success,Have [    0] Loca.
*******************************
Receive Success.i = <111>.
队列可用消息 = 4.
*******************************
Success Have [    0] Loca.
Fail,Queue is FULL,Reset!.
Receive Fail.


问题描述:
两个Task往同一个队列传数据,接收函数接收到立即传出,并且接收函数优先级高于发送函数,为什么通过uxQueueSpaceAvaliable查询队列空间再减少。
FreeRTos不是接收数据后就销毁吗,如果空间不断减少,那对于大量数据的接收不是太浪费空间了吗。

初来论坛,问题描述可能不够精确,望海涵。

eric2013 发表于 2024-3-13 09:08:31

这个打印内容是最开始的吗,如果是最开始的,那有点诡异,成了发送先执行,接收后执行了。

Success Have [    4] Loca.
Success,Have [    3] Loca.
*******************************
Receive Success.i = <222>.
队列可用消息 = 1.

summer_f 发表于 2024-3-20 11:43:45

前面有一条调试信息,也是发送先进行接收后进行,你说我才意识到确实诡异,后面就是循环输出信息了,硬件用的ESP32的板子,我也看了ESP32里相关FreeRtos的相关文档,确实没发现问题出在哪里:(
这两天没看帖子,回复晚了,不好意思:loveliness:
Creat queue Successfully.
Success,Have [    4] Loca.
*******************************
Receive Success.i = <111>.
队列可用消息 = 1.
*******************************
Success Have [    4] Loca.
Success,Have [    3] Loca.
*******************************
Receive Success.i = <222>.
队列可用消息 = 1.
*******************************
Success Have [    3] Loca.
Success,Have [    2] Loca.
*******************************
Receive Success.i = <111>.
队列可用消息 = 2.
*******************************
Success Have [    2] Loca.
Success,Have [    1] Loca.
*******************************
Receive Success.i = <222>.
队列可用消息 = 3.
*******************************
Success Have [    1] Loca.
Success,Have [    0] Loca.
*******************************
Receive Success.i = <111>.
队列可用消息 = 4.
*******************************
Success Have [    0] Loca.
Fail,Queue is FULL,Reset!.
Receive Fail.
Success Have [    4] Loca.
Success,Have [    3] Loca.
*******************************
Receive Success.i = <222>.   
队列可用消息 = 1.
*******************************
Success Have [    3] Loca.
Success,Have [    2] Loca.
*******************************
Receive Success.i = <111>.   
队列可用消息 = 2.
*******************************
Success Have [    2] Loca.
Success,Have [    1] Loca.
*******************************
Receive Success.i = <222>.   
队列可用消息 = 3.
*******************************
Success Have [    1] Loca.
Success,Have [    0] Loca.
*******************************
Receive Success.i = <111>.
队列可用消息 = 4.
*******************************
Success Have [    0] Loca.
Fail,Queue is FULL,Reset!.
Receive Fail.

summer_f 发表于 2024-3-20 11:52:58

初学者,对一些内容的理解偏差可能比较大,还是得多多研究源码了:loveliness:
页: [1]
查看完整版本: 关于队列先入先出的一点疑问