142 votes

Sémaphore - Quelle est l'utilité du comptage initial ?

http://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim.aspx

Pour créer un sémaphore, je dois fournir un nombre initial et un nombre maximal. MSDN indique qu'un compte initial est -

Le nombre initial de demandes de qui peuvent être accordées simultanément.

Bien qu'il soit indiqué que le nombre maximum est de

Le nombre maximum de demandes pour le qui peuvent être accordées simultanément.

Je comprends que le nombre maximum est le nombre maximum de threads qui peuvent accéder simultanément à une ressource, mais à quoi sert le nombre initial ?

Si je crée un sémaphore avec un nombre initial de 0 et un nombre maximal de 2, aucun de mes threads ne peut accéder à la ressource. Si je fixe le nombre initial à 1 et le nombre maximum à 2, seul un thread du pool de threads peut accéder à la ressource. Ce n'est que lorsque je fixe le compte initial et le compte maximum à 2 que 2 threads peuvent accéder à la ressource simultanément. Je ne comprends donc pas très bien l'importance du nombre initial.

SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 2); //all threadpool threads wait
SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 2);//only one thread has access to the resource at a time
SemaphoreSlim semaphoreSlim = new SemaphoreSlim(2, 2);//two threadpool threads can access the resource concurrently

118voto

Brian Gideon Points 26683

Je ne comprends donc pas très bien la signification du décompte initial.

Un point important qui peut s'avérer utile est que Wait décrémente le nombre de sémaphores et Release l'incrémente.

initialCount est le nombre d'accès aux ressources qui seront autorisés immédiatement. En d'autres termes, il s'agit du nombre de fois où l'accès à la ressource est autorisé. Wait peut être appelée sans blocage immédiatement après l'instanciation du sémaphore.

maximumCount est le nombre le plus élevé que le sémaphore peut obtenir. C'est le nombre de fois où Release peut être appelé sans lever d'exception en supposant que initialCount était de zéro. Si le initialCount est fixé à la même valeur que maximumCount puis en appelant Release immédiatement après l'instanciation du sémaphore lèvera une exception.

109voto

SVGreg Points 1212

Oui, lorsque le nombre initial est fixé à 0, tous les threads attendent pendant que vous incrémentez la propriété "CurrentCount". Vous pouvez le faire avec Release() ou Release(Int32).

Release(...) - incrémente le compteur du sémaphore

Wait(...) - le décrémente

Vous ne pouvez pas incrémenter le compteur (propriété "CurrentCount") au-delà du nombre maximum que vous avez défini lors de l'initialisation.

Par exemple :

SemaphoreSlim^ s = gcnew SemaphoreSlim(0,2); //s->CurrentCount = 0
s->Release(2); //s->CurrentCount = 2
...

s->Wait(); //Ok. s->CurrentCount = 1
...

s->Wait(); //Ok. s->CurrentCount = 0
...

s->Wait(); //Will be blocked until any of the threads calls Release()

16voto

Karmastan Points 4092

Combien de threads voulez-vous pouvoir accéder à la ressource en même temps ? Fixez votre nombre initial à ce chiffre. Si ce nombre n'est pas appelé à augmenter au cours de la vie du programme, fixez votre nombre maximum à ce nombre également. De cette façon, si vous avez une erreur de programmation dans la façon dont vous libérez la ressource, votre programme se plantera et vous le fera savoir.

(Il existe deux constructeurs : l'un qui ne prend qu'une valeur initiale et l'autre qui prend en plus le nombre maximum. Utilisez celui qui convient).

7voto

Theodor Zoulias Points 1088

Normalement, lorsque le SemaphoreSlim est utilisé comme étrangleur, les deux initialCount y maxCount ont la même valeur :

var semaphore = new SemaphoreSlim(maximumConcurrency, maximumConcurrency);

...et le semaphore est utilisé avec ce modèle :

await semaphore.WaitAsync(); // or semaphore.Wait();
try
{
    // Invoke the operation that must be throttled
}
finally
{
    semaphore.Release();
}

En initialCount configure la politique de concurrence maximale, et l'option maxCount garantit que cette politique ne sera pas violée. Si vous omettez le deuxième argument (l'option maxCount ), votre code fonctionnera tout aussi bien, à condition qu'il ne contienne pas de bogues. S'il y a un bogue, et que chaque WaitAsync peut être suivi de plusieurs Release , alors le maxCount vous aidera à détecter ce bogue avant qu'il ne se retrouve dans la version publiée de votre programme. Le bogue apparaîtra sous la forme d'un SemaphoreFullException Vous serez ainsi en mesure de le repérer et de l'éliminer avant qu'il ne cause de réels dommages (avant qu'il ne soit à l'origine de la violation de la politique de simultanéité maximale dans un environnement de production).

La valeur par défaut du maxCount Au cas où vous l'omettriez, l'argument est le suivant Int32.MaxValue ( code source ).

4voto

Abhineet Points 2899

Si vous souhaitez qu'aucun thread n'accède à votre ressource pendant un certain temps, vous passez le compte initial à 0 et si vous souhaitez accorder l'accès à tous les threads juste après avoir créé le sémaphore, vous passez la valeur du compte initial égale au compte maximum. Par exemple :

hSemaphore = CreateSemaphoreA(NULL, 0, MAX_COUNT, NULL) ;

//Do something here
//No threads can access your resource

ReleaseSemaphore(hSemaphore, MAX_COUNT, 0) ;

//All threads can access the resource now

Comme indiqué dans la documentation MSDN : "Une autre utilisation de ReleaseSemaphore est l'initialisation d'une application. L'application peut créer un sémaphore avec un compte initial de zéro. L'état du sémaphore est alors non signalé et l'accès à la ressource protégée est bloqué pour tous les threads. Lorsque l'application termine son initialisation, elle utilise ReleaseSemaphore pour augmenter le nombre de sémaphores à sa valeur maximale, afin de permettre un accès normal à la ressource protégée".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X