What is a once_flagsupposed to be initialized to? I've tried false and 0, and both have given errors similar to below (below is 0):
no viable conversion from 'int' to 'std::once_flag'
Here's how I am trying to use it. (I consider it bad style to not initialize statics even though the language initializes them, so I'd really prefer to have something there).
MyClass& GetMyClass()
{
static std::once_flag flag;
static MyClass cls;
std::call_once(flag, []() {
// Initialize class
});
return cls;
}
Update
If we look at the draft C++ standard section 30.4.4.1 Struct once_flag we can see the constructor is defined as:
constexpr once_flag() noexcept;
since it is a constexpr your static instance will be statically initialized and we can see an example in section 30.4.4.2 Function call_once that uses a static instance:
void g() {
static std::once_flag flag2;
std::call_once(flag2, initializer());
}
Original
If we look at the documentation to std::once_flag it says:
once_flag();
Cnstructs an once_flag object. The internal state is set to indicate that no function
has been called yet.
and if we look further at the document documentation for call_once we see the following example which demonstrates how to use std::once_flag:
#include <iostream>
#include <thread>
#include <mutex>
std::once_flag flag;
void do_once()
{
std::call_once(flag, [](){ std::cout << "Called once" << std::endl; });
}
int main()
{
std::thread t1(do_once);
std::thread t2(do_once);
std::thread t3(do_once);
std::thread t4(do_once);
t1.join();
t2.join();
t3.join();
t4.join();
}
with the following expected output:
Called once
Since your question has been answered elsewhere, as an alternative to the code you posted, you can also do this instead:
// private function in anonymous namespace or something
MyClass& initMyClass() {
static MyClass c;
/* initialize c */
return c;
}
and then have clients call
MyClass& GetMyClass() {
static MyClass& c = initMyClass();
return c;
}
because static initializations are thread safe now in C++11. And then you don't have to mess with call_once or anything.
what are you trying to do? you cannot initialize std::once_flag with any value because it only has one constructor that does not take any arguments.
http://en.cppreference.com/w/cpp/thread/once_flag
once_flag(); Constructs an once_flag object. The internal state is set
to indicate that no function has been called yet.
BTW, what is the reason that you consider not initialize statics variable is a bad style?
ONCE_FLAG_INIT
EDIT: C only, not C++. Defined in <threads.h>.
Related
I'm trying to implement a class to track the performances of a multithreaded code and am running into the following issue.
The tracker should have a single instance, thus the singleton pattern.
In order to count object creation and function execution accross all the threads, I thought that using atomic member would be a good idea. But I can't seem to figure out a correct implementation.
This is a minimal code of what I wand to do:
#include <atomic>
#include <iostream>
class Counter
{
public:
static Counter& instance()
{
return instance_;
};
void increment()
{
counter_++;
};
private:
Counter ()
{
std::cout << "ctor counter" << std::endl;
};
~Counter ()
{
std::cout << "counter_: " << counter_ << std::endl;
std::cout << "dtor counter" << std::endl;
}
static Counter instance_;
std::atomic<int> counter_{0};
//int counter_ = 0;
};
Counter Counter::instance_ = Counter();
int main(void)
{
Counter::instance().increment();
Counter::instance().increment();
Counter::instance().increment();
return 0;
}
If the counter_ variable is an int, it works fine, but would not be thread safe.
If it is an atomic<int>, then the compiler tells me this:
g++ foo.cc
foo.cc:34:38: error: use of deleted function 'Counter::Counter(const Counter&)'
Counter Counter::instance_ = Counter();
^
foo.cc:4:7: note: 'Counter::Counter(const Counter&)' is implicitly deleted because the default definition would be ill-formed:
class Counter
^~~~~~~
foo.cc:4:7: error: use of deleted function 'std::atomic<int>::atomic(const std::atomic<int>&)'
In file included from foo.cc:1:0:
/usr/include/c++/7/atomic:668:7: note: declared here
atomic(const atomic&) = delete;
^~~~~~
I'm not sure I quite understand the problem. Any explanation/solution would be much appreciated.
Cheers
You could simplify by having std::atomic<int> counter_{0}; simply be a static class member instead of part of each instance. (Since you're ensuring that there's only one instance the class.)
Or if you're only using your "singleton" that way returning a reference to a static object, just make all of its members static so you don't need to even get a pointer to that single instance of it in the first place. Then it can just be a glorified namespace{} with public and private static member functions. I think the only point of a "singleton" is to delay initializing it until after static initialization by using a function-scoped static with a non-constant initializer, but you're not doing that.
The actual problem is in the copy-constructor of your class, which your static initializer uses the way you've written it. It constructs a temporary Counter(); and then copies it to static instance_ variable.
You can compile as C++17 where eliding of that copy is guaranteed (works on Godbolt with g++ -std=gnu++17 with your source untouched), or you can rewrite the initializer
Counter Counter::instance_; // default construct
Counter Counter::instance_{}; // explicitly default construct
Both of those work with g++ -std=gnu++11
The following code is an implementation of an alternative singleTon class that uses std::call_once in C++11. Basically, the variable static_instance is declared statically along with static_flag, and once calling getInstance function which is also static function i create the first and only instance of mySingle using call_once.
I'd be happy to hear for any comments regarding code correctness in terms of thread safety, and whether its behavior differ from the standard c++ implementation of defining static variable inside getinstance.
mySingle.h
class mySingle
{
static mySingle *static_instance;
static std::once_flag static_flag;
public:
mySingle();
virtual ~mySingle();
static mySingle* getInstance();
};
mySingle.cpp
#include "mySingle.h"
mySingle * mySingle::static_instance;
std::once_flag mySingle::static_flag;
mySingle::mySingle(){}
mySingle::~mySingle(){}
mySingle* mySingle::getInstance()
{
std::call_once(g_flag, [&]() { static_instance = new mySingle(); });
return (mySingle*) static_instance;
}
From the std c++ call_once, it says
Executes the Callable object f exactly once, even if called concurrently, from several threads.
So one would expect that this is thread safe
Imagine I have a C++ class called MyClass.
Imagine that I have no access to the source code of MyClass ... it is contained in a library and I am supplied only the library and the header file for MyClass.
Imagine that the class itself requires environment pre-configuration ... for example ... before the constructor of the class can be called, I need to do some setup. The class is normally meant to be used as follows:
void func() {
doGlobalSetup();
MyClass myInstance(1,2,3);
myInstance.doSomething();
...
}
Now I have the situation where we need to create a global instance of the class such as:
MyClass myInstance(1,2,3);
int main(int argc, char *argv[]) {
doGlobalSetup();
myInstance.doSomething();
}
The problem is that in this story, the instance of MyClass is created before the call to doGlobalSetup(). It is instantiated before main() is called. What I want to do is either defer the creation of myInstance() till later or be able to run doGlobalSetup() somehow before the instantiation of the class.
This is a simplification of the actual story ... so let us assume:
I can't change the internals of MyClass.
There must be an instance variable called myInstance of type MyClass (I can't change the logic to MyClass *pMyInstance).
Many thanks for reading.
Since you've constrained the problem such that new cannot be used, you should be able to create the object as always and copy it to the global instance. For example:
MyClass createMyClass()
{
doGlobalSetup();
return MyClass(1, 2, 3);
}
MyClass myInstance = createMyClass();
int main()
{
myInstance.doSomething();
return 0;
}
Does it suit your needs?
namespace
{
int doStaticGlobalSetup()
{
doGlobalSetup();
return 0;
}
}
MyClass myInstance(doStaticGlobalSetup() + 1,2,3);
int main() {
myInstance.doSomething();
return 0;
}
If you absolutely have to defer any constructor calls until after global initialization is done, and want to be sure that no static order initialization fiasco happens, there is a way: make myInstance a reference to uninitialized block of memory and create object in it using placement new after global initializaton.
#include <iostream>
#include <type_traits>
struct foo
{
foo() { std::cout << "created\n"; }
void meow() { std::cout << "used\n"; }
~foo() { std::cout << "destroyed\n"; }
};
void doGlobalSetup() { std::cout << "Global setup\n"; }
//Actual implementation
namespace {
typename std::aligned_storage<sizeof(foo), alignof(foo)>::type bar;
}
foo& instance = reinterpret_cast<foo&>(bar);
//Allows automatic creation and destruction
struct initializer
{
initializer()
{
if (!initialized)
new (&instance) foo();
initialized = true;
}
~initializer()
{
if(initialized)
instance.~foo();
initialized = false;
}
private:
static bool initialized;
};
bool initializer::initialized = false;
int main()
{
doGlobalSetup();
initializer _;
instance.meow();
}
Use a static variable inside a function.
MyClass &myInstance() {
doGlobalSetup();
static MyClass myInstance(1,2,3);
return myInstance;
}
void func() {
myInstance().doSomething();
}
You probably already got the answer you wanted. But just to cover the whole spectrum: if, for some reason, you want to make sure that other places in the code don't accidentally construct MyClass independently of your global variable--and before the global setup has been made--you need to solve this with linking.
If you're on Linux, you can LD_PRELOAD a shared-object containing just the symbol for MyClass's constructor. In it, you declare the setup function accordingly, and let the dynamic linker do the job for you. Then, inside the constructor, you call the setup function, and then do a dlsym("...", RTLD_NEXT) to get the pointer to the original constructor, and you call it, passing it the arguments you got. Of course, you maintain and check a static flag for whether setup has already been performed.
Again, this is probably overkill for you, but I'm posting it just in case someone needs (and is able to use) this kind of solution.
P.S. This is what you get when you rely on global state! :)
First, bear in mind that given a library init function like doGlobalSetup there is a distinct nonzero chance the library will just not work if you create a global instance.
Otherwise it's super easy to create an initializer with the comma operator:
bool do_my_setup = (doGlobalSetup(), true);
MyClass myInstance(1,2,3);
Within the GCC compiler environment there is a function attribute capability called constructor. This allows us to flag a function definition with the ability for it to be automatically invoked before main is called and, most importantly before any class constructors are invoked.
Referring back to the original problem definition ... if the doGlobalSetup() function is modified from:
void doGlobalSetup() { ... }
to
__attribute__((constructor)) void doGlobalSetup() { ... }
then its invocation will occur before main is called and also before any static class instance constructors are called. The explicit call to this function would also be removed from main() as its work has been performed implicitly.
I am using g++ 4.7 with the c++11 flag. In this demo:
#include <iostream>
#include <thread>
class do_work
{
public:
void operator()()
{
std::cout << "Doing work..." << std::endl;
}
};
void foo()
{
}
int main()
{
// Does not work
std::thread t(do_work);
t.join(); // error: request for member ‘join’ in ‘t’, which is of non-class type ‘std::thread(do_work)’
// Works
std::thread t2(foo);
t2.join();
return 0;
}
I can successfully call join() on a thread that was created with a function as its constructor argument, but I cannot call join() (see the error inline) on a thread that was created with a functor as its constructor argument. Can anyone explain this?
You've declared t as a function taking do_work and returning std::thread.
You probably want to write
do_work worker;
std::thread t{worker};
or
std::thread t{do_work{}};
or
std::thread t((do_work()));
Note that
std::thread t(do_work());
won't work; it's vexingly parsed as declaring a function t taking a function that takes no arguments and returns do_work, and returning std::thread. Wrapping the do_work temporary with parentheses or using uniform initializer syntax (at any point) will fix it.
This is a good reason to get into the habit of using uniform initializer syntax wherever possible; if you'd written
std::thread t{do_work}; // incorrect
then compilation would have failed on that line instead of the join.
Now that C++11 has multithreading I was wondering what is the correct way to implement lazy initialized singleton without using mutexes(for perf reasons).
I came up with this, but tbh Im not really good at writing lockfree code, so Im looking for some better solutions.
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
# include <atomic>
# include <thread>
# include <string>
# include <iostream>
using namespace std;
class Singleton
{
public:
Singleton()
{
}
static bool isInitialized()
{
return (flag==2);
}
static bool initizalize(const string& name_)
{
if (flag==2)
return false;// already initialized
if (flag==1)
return false;//somebody else is initializing
if (flag==0)
{
int exp=0;
int desr=1;
//bool atomic_compare_exchange_strong(std::atomic<T>* obj, T* exp, T desr)
bool willInitialize=std::atomic_compare_exchange_strong(&flag, &exp, desr);
if (! willInitialize)
{
//some other thread CASed before us
std::cout<<"somebody else CASed at aprox same time"<< endl;
return false;
}
else
{
initialize_impl(name_);
assert(flag==1);
flag=2;
return true;
}
}
}
static void clear()
{
name.clear();
flag=0;
}
private:
static void initialize_impl(const string& name_)
{
name=name_;
}
static atomic<int> flag;
static string name;
};
atomic<int> Singleton::flag=0;
string Singleton::name;
void myThreadFunction()
{
Singleton s;
bool initializedByMe =s.initizalize("1701");
if (initializedByMe)
s.clear();
}
int main()
{
while (true)
{
std::thread t1(myThreadFunction);
std::thread t2(myThreadFunction);
t1.join();
t2.join();
}
return 0;
}
Note that clear() is just for testing, real singleton wouldnt have that function.
C++11 removes the need for manual locking. Concurrent execution shall wait if a static local variable is already being initialized.
§6.7 [stmt.dcl] p4
If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
As such, simple have a static function like this:
static Singleton& get() {
static Singleton instance;
return instance;
}
This will work all-right in C++11 (as long as the compiler properly implements that part of the standard, of course).
Of course, the real correct answer is to not use a singleton, period.
Maybe the easiest way to implement a singleton using C++11 is:
WARNING: Although this works according to the C++11 standard (static initialisers are thread-safe), this is not implemented correctly in Microsoft Visual C++ 2012 (static initialisers are NOT thread-safe). If you are targeting VC2012, then you have to use a different approach, as it does not fully implement the C++11 standard.
class Singleton {
public:
static Singleton& Instance() {
// Since it's a static variable, if the class has already been created,
// it won't be created again.
// And it **is** thread-safe in C++11.
static Singleton myInstance;
// Return a reference to our instance.
return myInstance;
}
// delete copy and move constructors and assign operators
Singleton(Singleton const&) = delete; // Copy construct
Singleton(Singleton&&) = delete; // Move construct
Singleton& operator=(Singleton const&) = delete; // Copy assign
Singleton& operator=(Singleton &&) = delete; // Move assign
// Any other public methods.
protected:
Singleton() {
// Constructor code goes here.
}
~Singleton() {
// Destructor code goes here.
}
// And any other protected methods.
}
IMHO, the best way to implement singletons is with a "double-check, single-lock" pattern, which you can implement portably in C++ 11:
Double-Checked Locking Is Fixed In C++11
This pattern is fast in the already-created case, requiring only a single pointer comparison, and safe in the first-use case.
As mentioned in previous answer, C++ 11 guarantees construction-order safety for static local variables Is local static variable initialization thread-safe in C++11? so you are safe using that pattern. However, Visual Studio 2013 does not yet support it :-( See the "magic statics" row on this page, so if you are using VS2013 you still need to do it yourself.
Unfortunately, nothing is ever simple. The sample code referenced for the pattern above cannot be called from CRT initialization, because the static std::mutex has a constructor, and is thus not guaranteed to be initialized before the first call to get the singleton, if said call is a side-effect of CRT initialization. To get around that, you have to use, not a mutex, but a pointer-to-mutex, which is guaranteed to be zero-initialized before CRT initialization starts. Then you would have to use std::atomic::compare_exchange_strong to create and use the mutex.
I am assuming that the C++ 11 thread-safe local-static-initialization semantics work even when called during CRT initialization.
So if you have the C++ 11 thread-safe local-static-initialization semantics available, use them. If not, you have some work to do, even moreso if you want your singleton to be thread-safe during CRT initialization.
template<class T>
class Resource
{
Resource<T>(const Resource<T>&) = delete;
Resource<T>& operator=(const Resource<T>&) = delete;
static unique_ptr<Resource<T>> m_ins;
static once_flag m_once;
Resource<T>() = default;
public :
virtual ~Resource<T>() = default;
static Resource<T>& getInstance() {
std::call_once(m_once, []() {
m_ins.reset(new Resource<T>);
});
return *m_ins.get();
}
};
It is hard to read your approach as you are not using the code as intended... that is, the common pattern for a singleton is calling instance() to get the single instance, then use it (also, if you really want a singleton, no constructor should be public).
At any rate, I don't think that your approach is safe, consider that two threads try to acquire the singleton, the first one that gets to update the flag will be the only one initializing, but the initialize function will exit early on the second one, and that thread might proceed to use the singleton before the first thread got around to complete initialization.
The semantics of your initialize are broken. If you try to describe / document the behavior of the function you will have some fun, and will end up describing the implementation rather than a simple operation. Documenting is usually a simple way to double check a design/algorithm: if you end up describing how rather than what, then you should get back to design. In particular, there is no guarantee that after initialize completes the object has actually been initialized (only if the returned value is true, and sometimes if it is false, but not always).
#pragma once
#include <memory>
#include <mutex>
namespace utils
{
template<typename T>
class Singleton
{
private:
Singleton<T>(const Singleton<T>&) = delete;
Singleton<T>& operator = (const Singleton<T>&) = delete;
Singleton<T>() = default;
static std::unique_ptr<T> m_instance;
static std::once_flag m_once;
public:
virtual ~Singleton<T>() = default;
static T* getInstance()
{
std::call_once(m_once, []() {
m_instance.reset(new T);
});
return m_instance.get();
}
template<typename... Args>
static T* getInstance2nd(Args&& ...args)
{
std::call_once(m_once, [&]() {
m_instance.reset(new T(std::forward<Args>(args)...));
});
return m_instance.get();
}
};
template<typename T> std::unique_ptr<T> Singleton<T>::m_instance;
template<typename T> std::once_flag Singleton<T>::m_once;
}
This version complies to be concurrent free where c++11 standard is not guaranteed to be 100% supported. It offers also a flexible way to instantiate the "owned" instance.
Even if the magic static word is enough in c++11 and greater the developer may have the necessity to get much more control over the instance creation.