2010-07-05 6 views
2

Je dois implémenter une fonction simple appelée à partir de plusieurs threads. La logique de la fonction est simple - pensez aux courses de chevaux - seul le premier cheval peut obtenir la médaille d'or une fois que nous avons un gagnant la course est terminée.Comment implémenter une fonction multithread simple

class ConditionalOrderGroup 
{ 
    private volatile bool _locked = false; 
    private List<ConditionalOrder> _ConditionalOrderList = null;   

public bool LockGroup(ConditionalOrder initiator) 
{ 
    // this is finishline - we need to let only the first one proceed 
    if (_locked) 
     return false; 
    else 
    { 
     _locked = true; 
    } 

    // this is what winner gets 
    foreach (ConditionalOrder order in _ConditionalOrderList) 
    { 

     \\ cancel other orders 
    } 

    return true; 
} 
} 

Je ne suis pas satisfait

if (_locked) 
    return false; 
else 
{ 
    _locked = true; 
} 

si deux ordres peuvent passer si contrôle et passez à autre . Comment réécrire ce code sans utiliser verrouiller déclaration?

MISE À JOUR Je veux dire que mon but n'est pas d'utiliser une méthode de blocage comme une instruction lock.

Répondre

2

Vous avez besoin d'un objet distinct, privé et utiliser le built-in locking:

private object padLock = new object(); // 1-to-1 with _ConditionalOrderList 

if (Monitor.TryEnter(padLock)) 
{ 
    try 
    { 
     // cancel other orders 

     return true; 
    } 
    finally 
    { 
     Monitor.Exit(padLock); 
    } 
} 
else 
{ 
    return false; 
} 
+0

Il a dit sans utiliser les verrous. – Martin

+1

Super! C'est exactement ce dont j'ai besoin d'une méthode non bloquante. –

+1

@Martin: Il a dit sans l'instruction * lock *. Ce qu'il fait déjà est un verrou (bien que brut) en soi. – Mizipzor

1

Utilisez la classe Interlocked pour modifier les valeurs de la variable dans un fil de manière sûre.

1

sur ce decyclone expansion dit au sujet agrafé, c'est exactement comment vous le faire:

const int LOCKED = 1; 
const int UNLOCKED = 0; 

volatile int lockState = UNLOCKED; 

public bool Foo() 
{ 
    try 
    { 
     //locking 
     //compare exchange returns the value that was in lockState before the compareExchange operation, so from that you can determine if you grabbed the lock or not 
     //if it was locked before, then you know the lock is not yours 
     if (Interlocked.CompareExchange(ref lockState, UNLOCKED, LOCKED) == LOCKED) 
      return false; 

     //lock is yours, do whatever stuff you like here, including throw exceptions 
    } 
    finally 
    { 
     //unlocking 
     //because this is in finally this lock will be released even if something goes wrong with your code 
     Interlocked.Exchange(ref lockstate, UNLOCKED); 
    } 
} 
+0

Oui, mais c'est un approximation approximative de ce que fait la classe Monitor. Je fais plutôt confiance à un cours de BCL si je le peux. Surtout quand il s'agit de parallélisme. –

Questions connexes