Queues or global variable?

Hello,

I have a beginner question.

If I have Task1 (read only) that only reads from a single queue that Task2 (write only) sends to and only one value is sent (integer value of an ADC), then it doesn’t make much sense to use a global variable instead of a queue?

Now I have a queue with one element and no waiting time. With two or more elements and waiting time in the queue, the latency is too high.

Using a queue doesn’t seem to make sense to me. A global variable makes more sense, doesn’t it?

Or do I always have to use queues because of thread safety?
But with only one value and only Task1 is reading and Task2 ist sending, there can’t be any interference, can there?

Best wishes

a queue in your scenario works as a shock absorber, meaning it helps you deal with scenarios where on the average, your work off your items fast enough but sometimes your consumer gets stalled and therefore your producer must buffer some data, allowing your consumer slack time to work off all incoming items without losing any.

If the flow pattern is always predictable and serves real time requirements(ie the consumer always handles input faster than the producer produces new one), a queue my indeed be not necessary. If the pattern is predictable such that the producer always produces input faster than the consumer can get it out the door, a queue of any depth won’t help either because sooner or later you will lose data.

2 Likes

What controls when Task1 reads and Task2 write.

My guess is Task 1 goes ready as soon as Task2 writes a word, but Task 2 then goes off and reads a second value using up the CPU, and then blocks on the full Queue, when Task 1 then runs.

With a global variable, you have nothing to tell task 1 to wake up and take the value, but would need to be “busy looping” waiting for it, which just wastes time.

1 Like

It also depends on the priorities of these tasks. We probably would be able to help you better if you provide more context and describe the problem that you are trying to solve.

1 Like

And here is my 2 cents:

I think there is nothing against sharing a global variable. I have an application in which “the current temperature” is stored in a variable, encapsulated in a function, accessible for all tasks:

    static int last_temp;
    int get_current_temperature()
    {
        return last_temp;
    }

If you want Task1 to check/read the latest value, you can also notify it. Task2 will call xTaskNotify(), and when Task1 has nothing to do, it will block on a call to xTaskNotifyWait().

When two tasks exchange a series values, and you want Task1 to see every new value, you can also consider using a stream buffer. You can have the stream buffer use task-notification, so that Task1 doesn’t have to do polling, as @richard-damon mentioned.

In FreeRTOS+TCP, the central IP-task uses a queue to receive messages. Queues are very useful when implementing API’s. It is recommended to give the server task a higher priority than the clients tasks, in order to prevent the queue from overflowing.

1 Like