C++ thread safe queue implementation I'm using this class for producer-consumer setup in C++:

#pragma once

#include &lt;queue&gt;
#include &lt;mutex&gt;
#include &lt;condition_variable&gt;
#include &lt;memory&gt;
#include &lt;atomic&gt;

template &lt;typename T&gt; class SafeQueue
{
public:
    SafeQueue() :
    _shutdown(false)
    {

    }

    void Enqueue(T item)
    {
        std::unique_lock&lt;std::mutex&gt; lock(_queue_mutex);
        bool was_empty = _queue.empty();
        _queue.push(std::move(item));
        lock.unlock();

        if (was_empty)
            _condition_variable.notify_one();
    }

    bool Dequeue(T&amp; item)
    {
        std::unique_lock&lt;std::mutex&gt; lock(_queue_mutex);

        while (!_shutdown &amp;&amp; _queue.empty())
            _condition_variable.wait(lock);

        if(!_shutdown)
        {
            item = std::move(_queue.front());
            _queue.pop();

            return true;
        }

        return false;
    }

    bool IsEmpty()
    {
        std::lock_guard&lt;std::mutex&gt; lock(_queue_mutex);
        return _queue.empty();
    }

    void Shutdown()
    {
        _shutdown = true;
        _condition_variable.notify_all();
    }

private:
    std::mutex _queue_mutex;
    std::condition_variable _condition_variable;
    std::queue&lt;T&gt; _queue;
    std::atomic&lt;bool&gt; _shutdown;
};


Most of it looks fine to me, but the Shutdown function looks like it might have some problems. If there are problems, what is the best way to 'unblock' a thread waiting on Dequeue when I want to stop it?
Your concerns are correct. The std::notify_one description says that


  Even if the shared variable is atomic, it must be modified under the mutex in order to correctly publish the modification to the waiting thread.




Code wise, return true/return false usually indicate a room for improvement. What you are actually returning is a state of _shutdown. Do it explicitly:

        if (!shutdown) {
            dequeue item;
        }
        return !_shutdown;


You may also notice that shutdown is always tested with negation. It indicates that the semantics is reversed. I recommend to replace shutdown with something like keep_running.