What is supposed to send to this queue function (try_get (T **data_out)) [SOLVED]

I have a std::string data that I want to send and receive in a normal server-client application.
I am confused what I should send to this function.
what variable or array I should send to that function? what is the size of the array or how should I declare it?
I made a silly declaration like below but it is not reasonable.

std::string cmd;
std::string *cmd1=&cmd;
std::string ** cmd2=&cmd1;
if(txqueue.try_get(cm2)){
...
}

Thanks in advance

Hello,

probably something like this

#include "mbed.h"
#include <string>

DigitalOut led(LED1);
Queue<string, 32> queue;
Thread thread;

void sender(){
    printf("Sender thread start\n");
    while(1){
        string *test = new string("data " + to_string((rand() % 100)) );
        //printf("Test address: %p\n", test);
        queue.try_put(test);
        thread_sleep_for(1000);
    }
}

int main(void)
{
    printf("Queue Test\n");
    thread.start(&sender);
    string *cmd;
    while (true) {
        if (queue.try_get(&cmd)){
            printf("Data from Queue - %s\n", cmd->c_str());
            //printf("CMD address: %p\n", cmd);
            delete cmd; 
        } 
        thread_sleep_for(500);
        led = !led;
    }
}

BR, Jan

HI,
Thank you very much. Would be good to have the example in the documentation.
I didn’t know that you should dynamically create the buffer.
Pointers are risky always … don’t know if that was a MUST to have it like that?

BTW why don’t you use std::string … only string? is it valid?
Thanks again,
BR, Mariwan

Hello Mariwan,

Documentation of Queue - API says

A Queue allows you to queue pointers to data from producer threads to consumer threads.

We can say the Queue is array of pointers with FIFO rules and additional functionality. That mean the Queue do not store any data directly or anything else, just holding the address where are the data stored.
With normal variable you risk lose data every time when your sender thread will be faster than consumer thred. Becasue Address will still same on input and your data will be overridden with every iteration. Then consumer will receive only last stored value and all other values stored between last two attempts of get, will be lost.
So use Queue like that does not make sense, from my point of view.

As a experimental workaround you can add a string array as a circular buffer inside the sender thread with same size like Queue and put address of that to Queue. That will solve the new keyword, but I don’t know how good solution it is, probably exist more effective solutions.

//include and so on
#define BUFF_SIZE  32
Queue<std::string, BUFF_SIZE> queue;

void sender(){
    printf("Sender thread start\n");
    std::string strArray[BUFF_SIZE];
    int i = 0;
    while(1){
        if (!queue.full()){
            strArray[i] = "data " + to_string((rand() % 100));
            printf("Send to Queue - %s\n", strArray[i].c_str());
            queue.try_put(&strArray[i]);
            thread_sleep_for(300);
            if(++i > BUFF_SIZE){
                i = 0;
                printf("Buffer counter reset\n");
            } 
        }
        else printf("Queue is full\n");
    }
}
//rest is same

Pointers are risky because programs are made by human, who does not assume every possibilities of faults, I think, but I am not expert :slight_smile:

However you can check also MemoryPool and Mail that can help with manage the memory.

yes, it is valid. The string and std::string point to same - typedef basic_string<char, char_traits<char>, allocator<char> > string;

BR, Jan

HI Jan,
Thank you very much for your help. I use the pointer np.
BR /Mariwan