Управление временем жизни статической переменной класса с помощью умного указателя C ++ - PullRequest
0 голосов
/ 08 ноября 2018

Я поддерживаю статическую переменную m_queue, которая содержит сообщения, которые выдвигаются основным потоком, поэтому вопрос заключается в том, когда рабочий поток каким-либо образом уничтожается, как я могу уничтожить ptrs сообщения в m_queue и выпустить память с использованием умных указателей? Я знаю ответ частично, чтобы использовать shared_ptr. Рекомендуется ли использовать shared_ptr для статических переменных? Если да, то как мне это сделать? Любая помощь будет оценена. Пожалуйста, укажите, есть ли какие-либо серьезные недостатки в коде.

typedef enum msg_type_t_ {
    MSG_SET,
    MSG_GET,
    MSG_NULL
} msg_type_t;

class msg_t {
public:
    std::string m_name;
    msg_type_t m_type;
    uint32_t m_id;
    msg_t(const std::string& name, const msg_type_t& type, uint32_t id) :
          m_name(name), m_type(type), m_id(id) {}
    ~msg_t()
    {
        std::cout << "Destructor called!" << std::endl;
    }
};
using msg_uptr_t = std::unique_ptr<msg_t>;

class workerThread {
private:
    std::string m_thread_name;
    std::thread* m_thread;
    std::condition_variable m_cond;
    std::mutex m_mtx;
    /* Message queue is shared amongst all the instances of the class */
    static std::queue<msg_uptr_t> m_queue;

public:
    /* Creating a new thread! */
    workerThread(const std::string& name)
    {
        m_thread_name = name;
        m_thread = new std::thread(&workerThread::thread_fn, this);
    }
    std::thread* getThread()
    {
        return m_thread;
    }
    const std::string& getThreadName()
    {
        return m_thread_name;
    }
    void thread_fn()
    {
        std::cout << "Created a new thread " << m_thread_name << std::endl;
        while(1) {
            msg_uptr_t msg_p;
            std::unique_lock<std::mutex> l(m_mtx);
            /* Wait until message queue is not empty!*/
            while(m_queue.empty()) {
                std::cout << "Waiting!" << std::endl;
                m_cond.wait(l,([this](){return !(m_queue).empty();}));
            }
            if(m_queue.empty()) {
                continue;
            }
            std::cout << "Message queue is not empty!, Continuing the processing!" << std::endl;
            std::cout << "Number of elements in the queue = " << m_queue.size() << std::endl;
            msg_p = std::move(m_queue.front());
            m_queue.pop();

            switch(msg_p->m_type) {
            case MSG_SET:
                std::cout << "Message Set Operation!" << std::endl;
                break;
            case MSG_GET:
                std::cout << "Message Get Operation!" << std::endl;
                break;
            case MSG_NULL:
                std::cout << "Null Operation!" << std::endl;
                break;
            default:
                std::cout << "Wrong Message type!" << std::endl;
                break;
            }
        }
    }
    void postMsg(msg_uptr_t msg_p)
    {
        std::cout << "Posting Message on to the queue!" << std::endl;
        std::cout << "Message Details!" << "Name : " << msg_p.get()->m_name<< std::endl;
        std::unique_lock<std::mutex> l{m_mtx};
        m_queue.push(std::move(msg_p));
        m_cond.notify_one();
    }
};
std::queue<msg_uptr_t> workerThread::m_queue;
...