3

I would like to have a C++11 RAII component to count how many resources of a certain type are present in a multithreaded environment. I wrote the following:

#include <atomic>
#include <iostream>

using namespace std;

class AtomicCounter
{
public:
    AtomicCounter(std::atomic< int > &atomic) : atomic(atomic) {
        int value = ++this->atomic;
        cerr << "incremented to " << value << endl;
    }

    ~AtomicCounter() {
        int value = --this->atomic;
        cerr << "decremented to " << value << endl;
    }

private:
    std::atomic< int > &atomic;
};

int main() {
    atomic< int > var;
    var = 0;
    AtomicCounter a1(var);
    {
    AtomicCounter a2(var);
    cerr << "Hello!" << endl;
    AtomicCounter a3(var);
    }
    cerr << "Good bye!" << endl;
    return 0;
}

The idea is that I create an AtomicCounter object in each resource (for example, the main thread function) and this keeps the associated atomic variable updated.

Is this component correct, even when used in a multithreaded environment? Is there a standard component that already does this?

Giovanni Mascellani
  • 1,218
  • 2
  • 11
  • 26
  • The main problem I see, especially for multithreaded use cases, is that your `atomic` could go out of scope and you are left with a dangling reference. Maybe a shared pointer would be an alternative. – mindriot Nov 09 '16 at 00:15
  • This doesn't strike me as making a whole lot of sense. If you want a count of available resources, you usually want access to those resources. That being the case, you frequently want to put the items into a collection, so you can find them (in which case the size of the collection tells you how many are available). – Jerry Coffin Nov 09 '16 at 00:18
  • 1
    @mindriot In my case I can assume the atomic stays in scope. However, good to know for a more general situation. – Giovanni Mascellani Nov 09 '16 at 09:19
  • @JerryCoffin I mostly need to know whether there are these resources around or not, so that I know when to do certain cleanup operations. Other than that, those resources (threads) work independently. Using a collection would require locking, while my implementation does not (if `atomic< int >` is lock free, as I think it is in most implementations). – Giovanni Mascellani Nov 09 '16 at 09:21
  • I was looking for exactly this. It does exactly what I need - a RAII way of counting in a multi threaded environment – Njål Arne Gjermundshaug Feb 11 '19 at 09:50
  • This looks like a counting semaphore to me. Typical examples such as in the responses to https://stackoverflow.com/questions/4792449/c0x-has-no-semaphores-how-to-synchronize-threads are often implemented using a mutex and a condition variable, but in principle it seems like an atomic should work. Stylistically though, think about encapsulating the value entirely in your AtomicCounter and passing references around to an instance of AtomicCounter, rather than using AtomicCounter to increment or decrement something that could be modified elsewhere. – Aaron Altman Apr 03 '19 at 18:43

0 Answers0