0

So I am trying to design a message queue between threads. So I have three files, main.cpp, MessageQueue.h, and MessageQueue.cpp.

MessageQueue.cpp

#include "MessageQueue.h"

template <class T>
void MessageQueue<T>::send(T &&msg) {

    //Locking the deque before entering the message onto the queue and so that no other thread accesses the message queue
    std::lock_guard<std::mutex> insertLock(_lock);

    //This is a modified message queue where, the message queue updates all the threads at the same time. Also, the receive function does not clear the message queue at all
    //the next iteration of the send function does that
    if(!_queue.empty) {
        _queue.clear();
    }

    //Placing the message at the back of the queue;
    _queue.emplace_back(msg);

    //This function will not notify
    _condition.notify_all();
}

template <class T>
void MessageQueue<T>::receive() {
    //Locing the deque with a unique lock
    std::unique_lock<std::mutex> retriveLock(_lock);

    //Wait for a message to be placed on the message queue
    _condition.wait(retriveLock, [this](){ return !_queue.empty(); });
}

MessageQueue.h

#ifndef MESSAGEQUEUE_H
#define MESSAGEQUEUE_H

#include <deque>
#include <mutex>
#include <condition_variable>

template <class T>
class MessageQueue {
public:
    void receive();
    void send(T &&msg);
    //void trigger();

private:
    std::deque<T> _queue;
    std::mutex _lock;
    std::condition_variable _condition;
};

#endif

main.cpp

class TempMessage {
    public:
        int value;
};

class T1 {
    public:
        static void waitingFunction1(MessageQueue<TempMessage> *_message) {
            while(true) {
                std::cout << "T1 is waiting ...\n";
                _message->receive();
                std::cout << "Conducting T1 operations ...\n";
            }
        }
};

class T2  {
    public:
        static void waitingFunction2(MessageQueue<TempMessage> *_message) {
            while(true) {
                std::cout << "T2 is waiting ...\n";
              std::this_thread::sleep_for(std::chrono::milliseconds(10));
                _message->receive();
                std::cout << "Conducting T2 operations ...\n";
            }
        }
};

int main() {
    Uint32 start, stop, duration;
    constexpr std::size_t kFramesPerSeconds{1};
    constexpr std::size_t kMsPerFrame{1000 / kFramesPerSeconds};
    MessageQueue<TempMessage> _messages;
    TempMessage tm;
    tm.value = 56;
    T1 *t1;
    T2 *t2;

    std::thread t1_thread(&T1::waitingFunction1, &_messages);
    std::thread t2_thread(&T2::waitingFunction2, &_messages);

    for(int i = 0; i < 1; i++) {
        start = SDL_GetTicks();

        _messages.send(std::move(tm));

        stop = SDL_GetTicks();

        duration = stop - start;
        if(duration < kMsPerFrame) {
            SDL_Delay(kMsPerFrame - duration);
        }
    }
}

When I compile the main.cpp using

g++ -std=c++11 -pthread main.cpp MessageQueue.cpp -lSDL2

I get the following error.

/tmp/ccFDwZ9S.o: In function `main':
temp.cpp:(.text+0x1bc): undefined reference to `MessageQueue<TempMessage>::send(TempMessage&&)'
/tmp/ccFDwZ9S.o: In function `T1::waitingFunction1(MessageQueue<TempMessage>*)':
temp.cpp:(.text._ZN2T116waitingFunction1EP12MessageQueueI11TempMessageE[_ZN2T116waitingFunction1EP12MessageQueueI11TempMessageE]+0x23): undefined reference to `MessageQueue<TempMessage>::receive()'
/tmp/ccFDwZ9S.o: In function `T2::waitingFunction2(MessageQueue<TempMessage>*)':
temp.cpp:(.text._ZN2T216waitingFunction2EP12MessageQueueI11TempMessageE[_ZN2T216waitingFunction2EP12MessageQueueI11TempMessageE]+0x58): undefined reference to `MessageQueue<TempMessage>::receive()'
collect2: error: ld returned 1 exit status

I don't really understand what I am doing wrong here. If anyone can help, that would be great.

Thanks

pshalin
  • 31
  • 3

0 Answers0