Thread-safe and unique execution of nested function - c++

I have a class MyClass whose function A is executed many times in parallel. Then, there is function B that should only be executed once. My initial setup looks simple but I doubt that it is thread-safe. How can I make it thread-safe? I'm using C++11.
class MyClass {
public:
void A() {
static bool execute_B = true;
if (execute_B) {
execute_B = false;
B();
}
}
private:
void B() {
std::cout << "only execute this once\n";
}
};

This is a primary use-case for std::atomic_flag:
class MyClass {
public:
void A() {
if (!execute_B_.test_and_set()) {
B();
}
}
private:
void B() {
std::cout << "only execute this once\n";
}
std::atomic_flag execute_B_ = ATOMIC_FLAG_INIT;
};
Online Demo
Note that any solutions involving static will allow only one invocation of MyClass::B, even across multiple MyClass instances, which may or may not make sense for you; assuming it doesn't make sense, this approach instead allows one invocation of MyClass::B per MyClass instance.

Yes, your code is not thead-safe: several threads can enter inside the body of if statement before execute_B will be set to false. Also, execute_B is not atomic, so you can have problems with visibility of changes between threads.
There are many ways you can make it thread-safe. Note that version (1), (2) and (4) will block other thread from executing A past the point of B execution, until B execution is finished.
1) Already mentioned std::call_once:
void A() {
static std::once_flag execute_B;
std::call_once(flag1, [this](){ B(); });
}
2) Calling B as result of initializating static variable:
void A() {
static bool dummy = [this](){ B(); return true; });
}
3) Using atomic exchange:
void A() {
static std::atomic<bool> execute_B = true;
if(execute_B.exchange(false, std::memory_order_acq_rel))
B();
}
4) Protecting check with a mutex (to avoid perfomance degradation later, use double-checked locking):
void A() {
static std::mutex m_;
static std::atomic<bool> execute_B = true;
if(execute_B.load(std::memory_order_acquire)) {
std::unique_lock<std::mutex> lk(m_);
if(execute_B.load(std::memory_order_relaxed)) {
B();
execute_B.store(false, std::memory_order_release);
}
}
}

Related

Thread safety of nested calls

I have two libs, one is thread safe called class A, The other lib called class B, which used class A to realize functions.
class A {
public:
void Get() {
std::lock_guard<std::mutex> lock(mutex_);
do_something
}
void Put() {
std::lock_guard<std::mutex> lock(mutex_);
do_something
}
private:
std::mutex mutex_;
};
class B {
public:
void Get() {
a.Get();
}
void Put() {
a.Put();
}
private:
A a;
};
So is class B thread safe?
I know that judging whether the thread is safe depends on whether the operation is atomic. If the put operate is not atomic then it's not thread safe. According to the above requirements, I think class B is not an atomic operation, so it is not thread-safe?
When the operation is not atomic, it may not be thread safe. for example we add some operate like below, Is it right?
class B {
public:
void Get() { // But Get is not atomic!!!
do_some_thing(); // atomic
a.Get(); // atomic
do_some_thing(); // atomic
}
void Put() {
do_some_thing();
a.Put();
do_some_thing();
}
private:
A a;
};
Thread safety concerns about the race conditions and data races.
Now, Since the methods of class B don't use any data directly but via delegating other methods in class A that as you said are thread-safe, the methods in B are thread-safe.

Guarding against vtable data race in derived destructor

Suppose I have the following code
#include <thread>
#include <iostream>
#include <atomic>
struct FooBase {
void start(){
run_condition_ = true;
t_ = std::thread([this](){
thread_handler();
});
}
virtual ~FooBase(){
run_condition_ = false;
if(t_.joinable())
t_.join();
}
protected:
virtual void thread_handler() = 0;
std::atomic_bool run_condition_{false};
private:
std::thread t_;
};
struct Foo : FooBase {
void thread_handler() override {
while(run_condition_){
std::cout << "Foo derived thread.." << std::endl;
}
}
};
int main(){
Foo f;
f.start();
getchar();
return 0;
}
Here I think because the destructor of the derived class Foo is called before FooBase the thread_handler vtable lookup happens in the base class IF the thread has not yet joined (still running) when the destructor of Foo is done. Since FooBase::thread_handler is pure virtual I am essentially guranteed a sigabort.
How do I guard against this? I hack my way through by not having thread_handler as pure virtual
virtual void thread_handler(){}
But I am lost as to how I can guard against this in the baseclass itself, I can implement a join_thread interface in the base class and call this from every derived class, but this seems cumbersome.
There's two issues here, neither of which match precisely what you described.
Your thread only gets stopped in ~FooBase(). This means that if Foo::thread_handler ever reads or writes to any of its members, they will get destroyed out from under it before the thread is stopped.
It you get to the destructor fast enough, it's possible that start() won't have actually invoked thread_handler() on the new thread by the time Foo gets destroyed - which will lead to the pure virtual call.
Either way, you need to ensure that by the time Foo is destroyed, anything related to thread_handler is done. This implies that every derived class from FooBase has to have, in its destructor:
run_condition_ = false;
if (t_.joinable()) {
t_join();
}
Setting aside that this directly doesn't work because t_ is private (you could wrap that into a protected stop()), it's an awkward design if all of your derived classes need to do something special just to work. You could instead put FooBase into its own class that just takes an arbitrary callable as an argument:
class joining_thread {
public:
joining_thread() = default;
~joining_thread() { stop(); }
bool running() const { return run_condition_.load(); }
template <typename... Args>
void start(Args&&... args) {
run_condition_ = true;
t_ = std::thread(std::forward<Args>(args)...);
}
void stop() {
run_condition_ = false;
if (t_.joinable()) t_.join();
}
private:
std::thread t_;
std::atomic_bool run_condition_{false};
};
And then your Foo can just have that as a member:
class Foo {
public:
void start() {
t_.start([this]{
while (t_.running()) { ... }
});
}
private:
// just make me the last member, so it's destroyed first
joining_thread t_;
};
That's still a little awkward with the whole running() thing, but hopefully the idea makes sense.
What you describe is not possible. You call "start" after you have constructed the object. The object is at that stage valid. You have avoided the common problem of calling a virtual function in the constructor, which would have caused issues. There is something called a memory barrier that is implied by any thread calls, so you can count on the fact the new thread will start with a view of memory that existed at the point it was created. Any thing that existed AND was not changed, is fine.
Your problem (as described in another answer) is that you can exit and destroy the object (and it's vtable), before the thread is complete.
The simplest fix for this is use a packaged task. Calling "get" on the future ensures the task is finished before you continue. Consider the code below
#include "stdafx.h"
#include <thread>
#include <iostream>
#include <atomic>
#include <future>
int main()
{
std::atomic<bool> stop{ false };
std::future<void> sync;
std::packaged_task<void()> task([&stop]()
{
while (!stop)
{
std::cout << "Running\n";
}
});
std::thread thread([&task]() {task();});
getchar();
stop = true;
task.get_future().get();
thread.join();
return 0;
}

Avoid destruction of object when executing futures in different threads

Imagine the following situation:
class A {
public:
folly::Future<folly::Unit> fooA(std::function<void()> callback);
};
class B {
public:
void fooB() {
a_->fooA([] { doSomethingCheap_(); }) /* Executed in thread 1 */
.via(exec_.get())
.then([] { doSomethingExpensive_(); }) /* Executed in thread 2 */
}
private:
std::shared_ptr<folly::Executor> exec_;
std::shared_ptr<A> a_;
void doSomethingCheap_();
void doSomethingExpensive_();
};
If at the time we end executing doSomethingCheap_() object B b will be destroyed then we will get segfault. Probably we can hold weak_ptr<B> in class A, but this approach is not extensible when we want to use class A not only in class B but also in some class C, ...
What is the best way avoiding it?
I'm not familiar with folly or what synchronization mechanisms you're using, but it seems like you could maybe use a Mutex-guarded bool that you capture and pass to the lambda calling doSomethingExpensive - this would be a "poor-man's join". Lock the mutex and then flip the bool to true. Alternately, you could use something like absl::Notification [since that what I know].
#include "absl/synchronization/notification.h"
class A {
public:
folly::Future<folly::Unit> fooA(std::function<void()> callback);
};
class B {
public:
void fooB() {
a_->fooA([] { doSomethingCheap_(); }) /* Executed in thread 1 */
.via(exec_.get())
.then([this] {
doSomethingExpensive_();
finished_.Notify();
}) /* Executed in thread 2 */
finished_.WaitForNotification();
}
private:
std::shared_ptr<folly::Executor> exec_;
std::shared_ptr<A> a_;
absl::Notification finished_;
void doSomethingCheap_();
void doSomethingExpensive_();
};
Ultimately, joining on the threads seems like the right way to go, I'm just not sure what is exposed in folly.

How to ensure that a method is executed only once for the lifetime of that object?

class MyObj{
public:
void myFunc(){
//ToBeExecutedJustOnce
}
};
I have a function that I want to be executable only once for the lifetime of MyObj. There may be many instances of MyObj, and each should be able to execute that function once. So if I have:
MyObj first;
MyObj second;
MyObj third:
first.myFunc(); // Should execute
second.myFunc(); // Should execute
third.myFunc(); // Should execute
first.myFunc(); // Should not execute
second.myFunc(); // Should not execute
third.myFunc(); // Should not execute
Options:
member variable: If I use a member variable, then other functions within MyObj can access it and change it.
global static variable: Can't work because first,second and third will all be checking the same variable.
local static: Same problem as #2.
The only solution I have found, is to have MyObj inherit from another class
MyOtherObj{
private:
bool _isInit = false;
public:
bool isInit(){
bool ret = true;
if (!_isInit){
ret = false;
_isInit = true;
}
return ret;
}
};
class MyObj : public MyOtherObj {
public:
void MyFunc(){
if (!isInit()){
//Do stuff...
}
}
};
Any better suggestion ?
EDIT: I don't care about thread safety!
EDIT: I do not want to execute the method in the constructor, simply because the method may need to be executed much later in the lifetime of the object....
Use std::once_flag. It is not resettable from other methods (then again, if you cannot trust other methods of the same class, your development process is highly questionable), easy to use, and it is even thread-safe if you ever do care about that. It can be a bit less efficient in a single-threaded program.
#include <mutex>
class MyObj {
public:
void MyFunc() {
std::call_once(initFlag, [=] {
//Do stuff...
});
}
private:
std::once_flag initFlag;
};
I don't see what is wrong with Option 1. If a class has so many responsibilities that another function may accidentally mess with the is_init member variable then the class should probably be made smaller.
However, if you want to encapsulate into another class that is less error prone, rather than using inheritance, I suggest you use composition:
class FirstTime {
bool first_time = true;
public:
bool operator()(){
if (!first_time)
return false;
first_time = false;
return true;
}
};
class MyObj {
FirstTime first_time;
public:
void myFunc(){
if (first_time()){
std::cout << "First time!\n";
}
}
};
Live demo.
As with Option 1, you should think about what copy/move behavior do you want. e.g Should a copy of an initialized MyObj be considered initialized?
I see three reasonable options:
Just use your option #1, a bool member variable.
Create a little class for an init flag, that can be set, but not be unset.
Use the public non-virtual interface (NVI) idiom, if you really want to be sure, that no-one messes with your flag.
A bool member variable
This would be my first choice. Make it private, of course. If your class has so many other data fields, that adding this new member appears painful, then this could be a sign of bad design of the entire class in the first place.
Often init() methods can be avoided completely by splitting up a class into two: A class A that contains the constructed data before the call to init() and a class B that is initialized upon construction. That way you can see if an object is initialized only by its type.
An init flag that can be set, but not reset
This class could look somewhat like this:
class InitFlag
{
public:
void set()
{
isSet_ = true;
}
operator bool() const
{
return isSet_;
}
private:
bool isSet_ = false;
};
This way, member functions cannot mess up your flag as easily. As an author of a class, you should be able to trust your member functions enough, that they don't set this flag, unless they are called init().
The non-virtual interface idiom
You create a base class with an init() function that is public and non-virtual. This function checks, if init() has been called before, calls a private purely virtual doInit() function which is supposed to do the actual initialization and sets the init flag after that. It looks like this:
class InitializeBase
{
public:
virtual ~InitializeBase() = default;
bool isInit() const
{
return isInit_;
}
void init()
{
assert( !isInit() );
doInit();
isInit_ = true;
}
private:
virtual void doInit() = 0;
bool isInit_ = false;
};
This has several security advantages:
Derived classes cannot modify isInit_.
Derived classes cannot call doInit(), as long as they don't make it public or protected (which would be very nasty). However, they can and must implement this function.
Hence doInit() function is statically guaranteed not to be called more than once, unless an assert() will trigger.
If you don't want the init() function to be public, then you can derive with the protected or the private attribute from InitializeBase.
The obvious drawback is that the design is more complicated and you get an additional virtual function call. For this reason the NVI idiom has become somewhat controversial.
Here's a variant that wraps a function in a class.
Once the function is called, it's replaced with one that does nothing.
const std::function<void()> nop = [](){};
class Once
{
public:
Once(std::function<void()> f) : m_function(f) {}
void operator()()
{
m_function();
m_function = nop;
}
private:
std::function<void()> m_function;
};
class Foo
{
public:
Foo(int x)
: m_function([this](){m_x += 1;}),
m_x(x) {}
int get() const { return m_x; }
void dostuff() { m_function(); }
private:
int m_x;
Once m_function;
};
int main()
{
Foo f(0);
cout << f.get() << endl; // 0
f.dostuff();
cout << f.get() << endl; // 1
f.dostuff();
cout << f.get() << endl; // 1
}
molbdnilo's answer is pretty good and was along the same lines I was thinking. I've changed a few things which I personally think makes it more idiomatic.
#include <iostream>
#include <functional>
class Once
{
bool isDone = false;
public:
void exec(std::function<void()> function)
{
if (!isDone)
{
function();
isDone = true;
}
}
};
class MyObj {
Once once = Once();
public:
void myFunc()
{
once.exec( []{
std::cout << "Hello, world!";
// do some stuff
});
}
};
int main()
{
MyObj foo = MyObj();
foo.myFunc();
foo.myFunc();
foo.myFunc();
}
The solution at the top is very good, but this might be a better solution for an interesting special case.
I assume that the method shall only be executed once because it modifies the state of the class. For the special case that the method initializes some parts of the class, I think it is best to use an optional, either boost::optional or std::optional or std::experimental::optional, depending on what is available to you:
#include <boost/optional.hpp>
class X
{
public:
void init()
{
if( ! _x )
{
_x.reset( 5 );
}
}
private:
boost::optional<int> _x;
};

Select mutex or dummy mutex at runtime

I have a class that is shared between several projects, some uses of it are single-threaded and some are multi-threaded. The single-threaded users don't want the overhead of mutex locking, and the multi-threaded users don't want to do their own locking and want to be able to optionally run in "single-threaded mode." So I would like to be able to select between real and "dummy" mutexes at runtime.
Ideally, I would have a shared_ptr<something> and assign either a real or fake mutex object. I would then "lock" this without regard to what's in it.
unique_lock<something> guard(*mutex);
... critical section ...
Now there is a signals2::dummy_mutex but it does not share a common base class with boost::mutex.
So, what's an elegant way to select between a real mutex and a dummy mutex (either the one in signals2 or something else) without making the lock/guard code more complicated than the example above?
And, before you point out the alternatives:
I could select an implementation at compile time, but preprocessor macros are ugly and maintaining project configurations is painful for us.
Users of the class in a multi-threaded environment do not want to take on the responsibility of locking the use of the class rather than having the class do its own locking internally.
There are too many APIs and existing usages involved for a "thread-safe wrapper" to be a practical solution.
How about something like this?
Its untested but should be close to OK.
You might consider making the template class hold a value rather than a pointer
if your mutexes support the right kinds of constructions. Otherwise you could specialise the MyMutex class to get value behaviour.
Also it's not being careful about copying or destruction .. I leave that as an exercise to the reader ;) ( shared_ptr or storing a value rather than a pointer should fix this)
Oh and the code would be nicer using RAII rather than explicit lock/unlock... but that's a different question.I assume thats what the unique_lock in your code does?
struct IMutex
{
virtual ~IMutex(){}
virtual void lock()=0;
virtual bool try_lock()=0;
virtual void unlock()=0;
};
template<typename T>
class MyMutex : public IMutex
{
public:
MyMutex(T t) : t_(t) {}
void lock() { t_->lock(); }
bool try_lock() { return t_->try_lock(); }
void unlock() { t_->unlock(); }
protected:
T* t_;
};
IMutex * createMutex()
{
if( isMultithreaded() )
{
return new MyMutex<boost::mutex>( new boost::mutex );
}
else
{
return new MyMutex<signal2::dummy_mutex>( new signal2::dummy_mutex );
}
}
int main()
{
IMutex * mutex = createMutex();
...
{
unique_lock<IMutex> guard( *mutex );
...
}
}
Since the two mutex classes signals2::dummy_mutex and boost::mutex don't share a common base class you could use something like "external polymorphism" to allow to them to be treated polymorphically. You'd then use them as locking strategies for a common mutex/lock interface. This allows you to avoid using "if" statements in the lock implementation.
NOTE: This is basically what Michael's proposed solution implements. I'd suggest going with his answer.
Have you ever heard about Policy-based Design ?
You can define a Lock Policy interface, and the user may choose which policy she wishes. For ease of use, the "default" policy is precised using a compile-time variable.
#ifndef PROJECT_DEFAULT_LOCK_POLICY
#define PROJECT_DEFAULT_LOCK_POLICY TrueLock
#endif
template <class LP = PROJECT_DEFAULT_LOCK_POLICY>
class MyClass {};
This way, your users can choose their policies with a simple compile-time switch, and may override it one instance at a time ;)
This is my solution:
std::unique_lock<std::mutex> lock = dummy ?
std::unique_lock<std::mutex>(mutex, std::defer_lock) :
std::unique_lock<std::mutex>(mutex);
Is this not sufficient?
class SomeClass
{
public:
SomeClass(void);
~SomeClass(void);
void Work(bool isMultiThreaded = false)
{
if(isMultiThreaded)
{
lock // mutex lock ...
{
DoSomething
}
}
else
{
DoSomething();
}
}
};
In general, a mutex is only needed if the resource is shared between multiple processes. If an instance of the object is unique for a (possibly multi-threaded) process, then a Critical Section is often more appropriate.
In Windows, the single-threaded implementation of a Critical Section is a dummy one. Not sure what platform you are using.
Just FYI, here's the implementation I ended up with.
I did away with the abstract base class, merging it with the no-op "dummy" implementation. Also note the shared_ptr-derived class with an implicit conversion operator. A little too tricky, I think, but it lets me use shared_ptr<IMutex> objects where I previously used boost::mutex objects with zero changes.
header file:
class Foo {
...
private:
struct IMutex {
virtual ~IMutex() { }
virtual void lock() { }
virtual bool try_lock() { return true; }
virtual void unlock() { }
};
template <typename T> struct MutexProxy;
struct MutexPtr : public boost::shared_ptr<IMutex> {
operator IMutex&() { return **this; }
};
typedef boost::unique_lock<IMutex> MutexGuard;
mutable MutexPtr mutex;
};
implementation file:
template <typename T>
struct Foo::MutexProxy : public IMutex {
virtual void lock() { mutex.lock(); }
virtual bool try_lock() { return mutex.try_lock(); }
virtual void unlock() { mutex.unlock(); }
private:
T mutex;
};
Foo::Foo(...) {
mutex.reset(single_thread ? new IMutex : new MutexProxy<boost::mutex>);
}
Foo::Method() {
MutexGuard guard(mutex);
}
Policy based Option:
class SingleThreadedPolicy {
public:
class Mutex {
public:
void Lock() {}
void Unlock() {}
bool TryLock() { return true; }
};
class ScopedGuard {
public:
ScopedGuard(Mutex& mutex) {}
};
};
class MultithreadingPolicy {
public:
class ScopedGuard;
class Mutex {
friend class ScopedGuard;
private:
std::mutex mutex_;
public:
void Lock() {
mutex_.lock();
}
void Unlock() {
mutex_.unlock();
}
bool TryLock() {
return mutex_.try_lock();
}
};
class ScopedGuard {
private:
std::lock_guard<std::mutex> lock_;
public:
ScopedGuard(Mutex& mutex) : lock_(mutex.mutex_) {}
};
};
Then it can be used as follows:
template<class ThreadingPolicy = SingleThreadedPolicy>
class MyClass {
private:
typedef typename ThreadingPolicy::Mutex Mutex;
typedef typename ThreadingPolicy::ScopedGuard ScopedGuard;
Mutex mutex_;
public:
void DoSomething(){
ScopedGuard guard(mutex_);
std::cout<<"Hello World"<<std::endl;
}
};