atomic counter and then compare value

Dear all,

Atomic type is often used for efficient synchronized value in multi-thread programming.

Here, I wrote a psuedo code. Does this code fail to enter the if scope just when the counter is MAXIMUM_NUM in parallel executions?

Of course, critical section technique such as mutex correct it,
but I do not lose the performance owing to atomic operation.

Could you know how to cope with this?

=====================================================================

#define MAXIMUM_NUM 10

atomic<int> counter;

counter.fetch_and_increment();
if(counter == MAXIMUM_NUM){
// some procedure is done counter is equal to 10
}

=====================================================================
1
2
3
4
5
6
7
++counter ;
if(counter == MAXIMUM_NUM){

    // some procedure is done if counter 
    // was equal to MAXIMUM_NUM when it was tested in the if condition
    // (we can't assume that counter would still be equal to MAXIMUM_NUM at this point)
}
Dear JLBorges

I apologize for my poor explanation of my conditions.

As my intention, when the above procedures just are called MAXIMUM_NUM times, the thread is expected to enter the scope in the if statement.

(If I am wrong, I am sorry) in your code, 1 line is not atomic operation so that when some threads simultaneously process the line, counter is not correctly incremented.

On the other hand, in my code, one thread first processes the counter increment, and then, before if condition is evaluated, other thread processes the counter increment, which fails my intended code behavior.

Do I need mutex or so?
P.S.

each thread entails their own special processes before entering the above procedures, so that I would like to keep the order correctly.
http://www.cplusplus.com/reference/atomic/atomic/operatorplusplus/
http://www.cplusplus.com/reference/atomic/atomic/fetch_add/

You use the result returned by whatever method you choose.
You can't increment and examine counter directly in two separate statements and expect success.

1
2
3
4
5
6
7
8
9
atomic<int> counter;

///

int t = ++counter;
if ( t == MAXIMUM_NUM ) {
    // if you still need counter == MAXIMUM_NUM here, then
    // you need a mutex
}

++counter is an atomic read-modify-write operation
https://en.cppreference.com/w/cpp/atomic/atomic/operator_arith


> one thread first processes the counter increment, and then,
> before if condition is evaluated, other thread processes the counter increment

To avoid that, this could be done:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <atomic>

constexpr int MAXIMUM_NUM = 10 ;
std::atomic<int> counter{0};

void foo()
{
    if( ++counter == MAXIMUM_NUM ) {

        // some procedure is done if value of counter after increment was equal to 10

    }

}
Dear salem c and JLBorges

I understood and appreciate your answers, which solve my worry perfectly.

Thank you so much.
Mitsuru wrote:
Atomic type is often used for efficient synchronized value

It's true that they are "often used" for that perceived reason, but it is far from often that they actually are efficient.
Dear Cubbi

Thank you for your opinion.

As possible as I can, I avoid shared data and use local one.

However, there is inevitable cases to depend on the former.

If you have alternative idea of efficient realization of thread-safe shared data, I would appreciate it if you could advise me.
Topic archived. No new replies allowed.