2011-01-16 20 views
51

http://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim.aspxSemáforo: ¿Cuál es el uso del recuento inicial?

Para crear un semáforo, necesito proporcionar un recuento inicial y un recuento máximo. MSDN afirma que es un recuento inicial -

El número inicial de solicitudes de el semáforo que se puede conceder simultáneamente.

Si bien afirma que cuenta máxima es

El número máximo de solicitudes de el semáforo que se puede conceder simultáneamente.

Entiendo que el recuento máximo es la cantidad máxima de subprocesos que pueden acceder a un recurso al mismo tiempo. Pero, ¿para qué sirve el recuento inicial?

Si creo un semáforo con un recuento inicial de 0 y un recuento máximo de 2, ninguno de mis subprocesos de subprocesos puede acceder al recurso. Si configuro el recuento inicial como 1 y el recuento máximo como 2, solo el subárbol de subprocesos puede acceder al recurso. Solo cuando establezco el recuento inicial y el recuento máximo como 2, 2 subprocesos pueden acceder al recurso al mismo tiempo. Entonces, ¿estoy realmente confundido sobre la importancia del recuento inicial?

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 
+2

¿Cómo es que nunca aceptó la respuesta de SVGreg? – john

Respuesta

1

De esta forma, cuando el hilo actual crea el semáforo puede reclamar algunos recursos desde el principio.

+0

Entonces, ¿quiere decir que cuando quiero dos hilos de trabajo para acceder al recurso, debería cambiar el recuento inicial? – Sandbox

+0

No. Es el hilo actual que reclama un recuento. Si no desea que el hilo actual reclame un pase de acceso 0 o use la sobrecarga con un parámetro. –

45

Sí, cuando el número inicial se establece en 0, todos los hilos estarán esperando mientras se incrementa la propiedad "CurrentCount". Puede hacerlo con Release() o Release (Int32).

de liberación (...) - se incrementará el contador de semáforo

espera (...) - se disminuirlo

Usted no puede incrementar el contador (propiedad "currentCount") mayor que el máximo cuenta que estableces en la inicialización.

Por ejemplo:

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() 
+1

Su código estará mejor presentado en la respuesta que como un comentario. – ChrisF

+0

Gracias. Porque pensé cómo resaltar el código. – SVGreg

+1

LOL es probablemente la quinta vez que llego a esta misma respuesta porque la documentación del constructor siempre me confunde sobre qué valores establecer. Cheers – BlueStrat

4

El número de threads es lo que quiere ser capaz de acceder a los recursos a la vez? Establezca su conteo inicial a ese número. Si ese número nunca va a aumentar a lo largo de la vida del programa, establezca su recuento máximo en ese número también. De esta forma, si tiene un error de programación en la forma de liberar el recurso, su programa se bloqueará y le avisará.

(Hay dos constructores: uno que sólo toma un valor inicial, y que, además, lleva el recuento máximo Uso según sea el caso..)

1

Si desea que ningún hilo debe tener acceso a su recurso para un tiempo , pasas el recuento inicial como 0 y cuando deseas otorgarle acceso a todos justo después de crear el semáforo, pasas el valor del recuento inicial igual al recuento máximo. Por ejemplo:

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 

Como se cita en MSDN Documentación- "Otro uso de ReleaseSemaphore es durante la inicialización de una aplicación.La aplicación puede crear un semáforo con un recuento inicial de cero. Esto establece el estado del semáforo en no señalado y bloquea todos los subprocesos para que no accedan al recurso protegido. Cuando la aplicación finaliza su inicialización, utiliza ReleaseSemaphore para aumentar la cuenta a su valor máximo, para permitir el acceso normal al recurso protegido."

+0

Disculpa, te di el ejemplo en C++, aunque puedo aclarar la duda. – Abhineet

28

Por lo tanto, estoy realmente confundido acerca de la importancia del conteo inicial?

Un punto importante que puede ayudar aquí es que Wait decrementa la cuenta del semáforo y Release lo incrementa.

initialCount es el número de recursos accesos que no se permitirá inmediatamente. O, en otras palabras, es el n la mayoría de las veces Wait se puede llamar sin bloqueo inmediatamente después de la creación de la instancia del semáforo.

maximumCount es la cuenta más alta que puede obtener el semáforo. Es la cantidad de veces que se puede invocar Release sin lanzar una excepción suponiendo que el recuento de initialCount fue cero. Si initialCount tiene el mismo valor que maximumCount y luego llama al Release inmediatamente después de la creación de la instancia del semáforo arrojará una excepción.

+3

¡Esto es tan útil! Había estado pensando en semáforos hacia atrás, ya que en initialCount está la cantidad de recursos BLOQUEADOS inicialmente, no la cantidad de recursos que están disponibles inmediatamente. Gracias. –

+1

@PhilipTenn, estoy de acuerdo - la documentación no es clara al respecto – BlueStrat

+0

acepté, deberían cambiar ese nombre de variable o actualizar los documentos – IronHide

0

Como MSDN lo explica en la sección Observaciones:

Si initialCount es menor que maximumCount, el efecto es el mismo que si el hilo actual había llamado WaitOne (maximumCount menos initialCount) veces. Si no desea reservar ninguna entrada para el hilo que crea el semáforo, use el mismo número para maximumCount y initialCount.

lo que si el conteo inicial es 0 y el máximo es 2 es como si WaitOne se ha llamado dos veces por el hilo principal, por lo que hemos alcanzado la capacidad (número de semáforo es 0 ahora) y ningún hilo puede entrar en el semáforo. De forma similar Si el recuento inicial es 1 y el máximo es 2, se ha llamado a WaitOnce una vez y solo puede entrar un hilo antes de que alcancemos la capacidad nuevamente, y así sucesivamente.

Si se utiliza 0 para el recuento inicial, siempre podemos llamar a Release (2) para aumentar el recuento de semáforos al máximo para permitir el máximo número de subprocesos para adquirir recursos.

Cuestiones relacionadas