3

I'm learning how to implement a thread safe singleton pattern in c++11 and later.

#include <iostream>
#include <memory>
#include <mutex>

class Singleton
{
public:
    static Singleton& get_instance();
    void print();

private:
    static std::unique_ptr<Singleton> m_instance;
    static std::once_flag m_onceFlag;
    Singleton(){};
    Singleton(const Singleton& src);
    Singleton& operator=(const Singleton& rhs);
};

std::unique_ptr<Singleton> Singleton::m_instance = nullptr;
std::once_flag Singleton::m_onceFlag;

Singleton& Singleton::get_instance(){
        std::call_once(m_onceFlag, [](){m_instance.reset(new Singleton());});
        return *m_instance.get();
};

void Singleton::print(){
    std::cout << "Something" << std::endl;
}

int main(int argc, char const *argv[])
{
    Singleton::get_instance().print();
    return 0;
}

The code compiles fine but when executing i receive the following Exception.

terminate called after throwing an instance of 'std::system_error'
what():  Unknown error -1
Aborted

i tried to debug the program with gdb. It seems that the exception is thrown when calling std::call_once. I'm not sure about what's happening but i assume that the lambda expression failed to create the object.

A second question. Is there a way to know what unknown error codes actually mean ? i think a -1 will not help much when trying to identify the problem.

Thanks for your help.

hannibal
  • 266
  • 4
  • 15

1 Answers1

5

This happens because you did not compile with the -pthread flag and are attempting to use utilities from the native threading library on your system.

As an alternative look into the following change to the singleton pattern definition in your example referred to as the "Meyers Singleton"

Singleton& Singleton::get_instance(){
    static Singleton instance;
    return instance;
}

This is thread safe, and will cause the instance variable to only be initialized once. This wikipedia article has a good explanation of how it possibly works under the hood https://en.wikipedia.org/wiki/Double-checked_locking. It is good to let the compiler arrange code for you whenever possible. Also as noted in the comments this question also has useful information about the above Is Meyers' implementation of the Singleton pattern thread safe?

Curious
  • 20,870
  • 8
  • 61
  • 146
  • Which part here requires `pthread`? Where do you see "use utilities from the native threading library"? – user7860670 Jun 20 '17 at 13:20
  • @VTT the `` header in OP's code and the subsequent call to `std::call_once()` requires synchronization – Curious Jun 20 '17 at 13:21
  • `` is one of the C++ standard library headers, `::std::call_once` is one of the C++ standard library routines. If the necessary libraries haven't been linked in then there would have been an "unresolved external symbol..." error. – user7860670 Jun 20 '17 at 13:30
  • @VTT see https://stackoverflow.com/questions/8649828/what-is-the-correct-link-options-to-use-stdthread-in-gcc-under-linux If you are wondering why the `-pthread` flag is required, that might be a good candidate for another question entirely – Curious Jun 20 '17 at 13:35
  • 1
    @Curious thanks for the detailed answer. i think i need to add Scott Meyer's books to my wishlist. – hannibal Jun 20 '17 at 13:40