2

If I want to have some bool flag that I want to share between threads and whose lifespan is unclear because thread1, thread2, ... could be the particular last thread to use it, how can I provide such a type?

I could obviously have a shared_ptr<bool> with a mutex to synchronize access to it. Without the shared_ptr, however, I would just use an atomic<bool> because it would do the job.

Now, can I combine both of the concepts by using a shared_ptr<atomic<bool>>?

If not, what would be the easiest way to have an undetermined-lifespan bool to share between threads? Is it the mutex?

It might be necessary to say that I have multiple jobs in my system and for each of the jobs I would like to provide an shared abort flag. If the job is already done, some thread that would like to abort the thread should not crash when it tries to set the flag. And if the thread that likes to abort the job does not keep the flag (or shared_ptr) to it, then the thread should still be able to read the flag without crash. However, if no thread uses the bool anymore, the memory should be frees naturally.

IceFire
  • 4,016
  • 2
  • 31
  • 51
  • 1
    What's wrong with global `std::atomic`? You don't really provide enough context for a better answer. – Richard Critten Aug 23 '16 at 09:52
  • @RichardCritten I've added a paragraph at the end giving a motivation... in short: I have many `bool`s and memory should be freed if no one is using it anymore – IceFire Aug 23 '16 at 09:59

1 Answers1

2

Once you have created your atomic bool:

std::shared_ptr<std::atomic<bool>> flag = std::make_shared<std::atomic<bool>>(false /*or true*/);

You should be fine to use this among threads. Reference counting and memory deallocation on std::shared_ptr are thread safe.

The other thing that might be of interest is if you want some threads to opt out of reference counting, then you can use:

std::weak_ptr<std::atomic<bool>> weak_flag = flag;

...

std::shared_ptr<std::atomic<bool>> temporary_flag = weak_flag.lock();

if (temporary_flag != nullptr)
{
   // you now have safe access to the allocated std::atomic<bool> and it cannot go out of scope while you are using it
}

// now let temporary_flag go out of scope to release your temporary reference count
keith
  • 5,122
  • 3
  • 21
  • 50
  • I have said reference counting and memory deallocating are thread safe. i.e. you are really concerned with the thread safety of the underlying object, and you deal with this properly by using shared_ptr appropriately. shared_ptr is "thread safe" just as long as you are passing a copy of it (or assinging to a copy via weak_ptr) to each thread i.e. don't access *the same instance* from difference threads, see [documentation](http://en.cppreference.com/w/cpp/memory/shared_ptr) – keith Aug 23 '16 at 11:00
  • Ah, I see. I would not even have come to the idea of just passing a reference of shared_ptr. This thread seems to say that the content is not threadsafe in any case, though?! http://stackoverflow.com/questions/9127816/stdshared-ptr-thread-safety-explained – IceFire Aug 23 '16 at 11:09
  • If you pass shared_ptr& to each thread, that is not thread safe, but assigning a new shared_ptr (via copy constructor) to each thread, then shared_ptr is thread safe, but the object being shared has no change to it's level of thread safety, hence also using atomic – keith Aug 23 '16 at 11:13
  • For clarity of this comment thread: I posted an answer assuming that `std::shared_ptr> is not thread-safe, but I was wrong, so I deleted the answer. – stefaanv Aug 23 '16 at 15:12