2010-10-25 9 views
3

J'ai une classe simple qui ressemble un peu à ceci:Démarrage et arrêt des opérations d'une manière thread-safe

@protocol Recorder 
@property(BOOL) isRunning; 
- (void) start; 
- (void) stop; 
@end 

Et les implémentations de la méthode:

- (void) start { 
    if (running) 
     return; 
    … 
    running = YES; 
} 

- (void) stop { 
    if (!running) 
     return; 
    … 
    running = NO; 
} 

Et je commencé à penser à fil sécurité. La solution actuelle n'est pas thread-safe, non? Que diriez-vous ceci:

- (void) start { 
    @synchronized(self) { 
     if (running) 
      return; 
     … 
     running = YES; 
    } 
} 

Est-ce exact, à condition que la méthode -stop est également synchronisé? Je n'aime pas l'imbrication supplémentaire introduite par @synchronized, cependant. Le verrouillage explicite fonctionnerait-il?

- (void) stop { 
    [startStopLock lock]; 
    if (running) 
     return; 
    … 
    running = YES; 
    [startStopLock unlock]; 
} 

Ou pourrais-je faire encore cela?

enum { Running, Stopped }; 
NSConditionLock *startStopLock; 

- (void) start { 
    if (![startStopLock tryLockWithCondition:Stopped]) 
     return; 
    … 
    [startStopLock unlockWithCondition:Running]; 
} 

Cette solution est-elle correcte? Feriez-vous les choses différemment?

Répondre

1

Quelle langue est-ce? Vous avez raison, la première version n'est pas sûre pour les threads.

La version synchronisée est sûre pour les threads. Avec un verrouillage explicite, vous devez faire attention de ne pas rater le déverrouillage sur le chemin de retour anticipé.

Si vous avez accès à des intrinsèques xchg verrouillées, vous pouvez le faire assez facilement avec une opération d'échange atomique. cmpxchg fonctionne également.

start() { 
    if (locked_xchg(running, YES) == YES) { 
     // the old value was YES, so nothing to do 
     return 
    } 
+0

Ceci est Objective-C sur iOS. Merci pour l'indice 'locked_xchg', j'ai' OSAtomicTestAndSet' qui devrait être à peu près le même. – zoul

+0

Pas de problème. C'est une erreur classique que les gens font. Malheureusement, notre produit Jinx ne fonctionne pas sur l'iPhone. Sinon, je recommanderais de l'utiliser pour aider à attraper ces courses. –