jeudi 30 juin 2016

make a simple NSInteger counter thread safe


I define a NSInteger counter and updated its value in a callback like the following code shows (callback is in another thread):

-(void) myFunc {
  NSLog(@"initialise counter...");
  // I try to use volatile to make it thread safe
  __block volatile NSInteger counter = 0;

  [self addObserver:myObserver withCallback:^{
     // this is in another thread
     counter += 1;
     NSLog(@"counter = %d", counter);
  }];
}

I use volatile keyword to make the counter thread safe, it is accessed in a callback block which belongs to another thread.

When I invoke myFunc two times:

// 1st time call
[self myFunc];
// 2nd time call
[self myFunc];

the output is like this:

initialise counter...
counter = 1;
counter = 2;
counter = 3;
counter = 4;
counter = 1; // weird
initialise counter...
counter = 2; // weird
counter = 3;
counter = 1; // weird
counter = 4;

It looks like the 2nd time call produce a counter with wrong initial value, and the output before counter=4 is counter=1 which is also weird.

Is it because my code is not thread safe even with volatile keyword? If so, how to make my counter thread safe? If it is thread safe, why I get weird output?


Aucun commentaire:

Enregistrer un commentaire