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