Semáforos o Monitores

10/08/2004 - 00:12 por Pedro Ayensa | Informe spam
Hola,
estoy buscando la forma de implementar Monitores que no sean mutex. En mi
proyecto quiero que sólo se puedan crear simultáneamente X instancias de una
clase, y el resto me gusaría que se quedaran a la espera de que alguna de
las creadas terminen su función. Había pensado que, como en UNIX, quizás
sería posible inicializar algún tipo de valor al número de instancias que
pueden crearse, y que cada vez que se creara una se decrementara hasta
llegar a 0, bloqueando a las sucesivas llamadas al constructor, pero sólo
encuentro el SyncLock.
¿Alguna idea que me pueda ayudar?
Gracias.

Preguntas similare

Leer las respuestas

#1 Drk
10/08/2004 - 09:39 | Informe spam
Te documento todas las formas de sincronización que tengo constancia que hay
en VB .NET a ver si te puede ayudar

SYNLOCK
-

Viene a ser como un Mutex pero subido al Framework en vez de trabajar a
nivel de Windows. Un ejemplo por ejemplo con el Synlock para ver en que
casos se puede utilizar. Primero aplicamos el ejemplo sin el atributo de
sincronización:

Imports System.Threading



Module Module1

Sub Main()

Prueba()

Console.ReadLine()

End Sub



Sub Prueba()

For i As Integer = 1 To 5

Dim h As New Thread(AddressOf Funcion)

h.Name = "Subproceso núm " & i.ToString

h.Start()

Next

End Sub



Sub Funcion()

For i As Integer = 1 To 100

Console.Write("Soy ")

Console.Write("un texto ")

Console.Write("de prueba ")

Console.Write("de sincronización ")

Console.Write("desde " & Chr(10) & " ")

Console.WriteLine(Thread.CurrentThread.Name)

Next

End Sub

End Module



Para hacerlo sincronizado y no se mezcle el texto al salir declararemos a
nivel de módulo:

Dim Var As String = "" 'Para que no sea Nothing



Y modificaremos la función Funcion():

Sub Funcion()

For i As Integer = 1 To 100

SyncLock (Var)

Console.Write("Soy ")

Console.Write("un texto ")

Console.Write("de prueba ")

Console.Write("de sincronización ")

Console.Write("desde " & Chr(10) & " ")

Console.WriteLine(Thread.CurrentThread.Name)

End SyncLock

Next

End Sub



MONITOR



Parecido al Synlock:

Monitor.Enter(obj)

'Código

Monitor.Exit(obj)

Monitor.Wait(400) 'Permite esperar



INTERLOCKED

-

Permite sobre una variable entera hacer incrementos, decrementos y
comparaciones utilizadas por varios hilos.
System.Threading.Interlocked.Increment(var) o .Decrement(var), esto
permitirá que sólo pueda entrar un solo hilo a la hora de hacerlo. Es como
una reducción del Synlock ya que actúa sobre una sola variable.





MUTEX



Permite establecer un token/testigo sobre una función, hasta que no esté
libre no podrá utilizar esa función otro hilo. Funciona a nivel de Windows
por lo que no está recomendado para trabajar en multiplataforma pero si es
el mejor a la hora de trabajar únicamente en Windows.



Dim m As New Mutex



Sub procedimiento()

m.WaitOne() ‘Para dar comienzo

'Código

m.ReleaseMutex() ‘Para finalizar

End Sub



READWRITERLOCK


Permite que lean muchos hilos a la vez pero a la hora de escribir únicamente
un hilo. Simulamos con un ejemplo, faltaría indicar procesos de lectura y
escritura:

Imports System.Threading



Module Module1

Sub main()

ProbarBloqueoLecturaEscritura()

Console.ReadLine()



End Sub



Dim rwl As New ReaderWriterLock

Dim rnd As New Random



Sub ProbarBloqueoLecturaEscritura()

Dim i As Integer

For i = 1 To 10

Dim t As New Thread(AddressOf HacerLaTarea12)

t.Name = i.ToString

t.Start()

Next

Thread.Sleep(20000)

End Sub



Sub HacerLaTarea12()

Dim i As Integer

Dim tNombre As String = Thread.CurrentThread.Name

'Ejecutar 10 operaciones de lectura y escritura. Las lecturas són
más frecuentes

For i = 1 To 10

If rnd.NextDouble < 0.8 Then

'Intentar realizar una operación de lectura

rwl.AcquireReaderLock(Timeout.Infinite) ‘Se espera si está
escribiendo

Console.WriteLine("El subproceso {0} está leyendo", tNombre)

Thread.Sleep(300)

Console.WriteLine("El subproceso {0} ha completado la
operación de lectura", _

tNombre)

rwl.ReleaseReaderLock()

Else

'Intentar realizar una operación de escritura

rwl.AcquireWriterLock(Timeout.Infinite) ‘Se espera si está
escribiendo

Console.WriteLine("El subproceso {0} está escribiendo",
tNombre)

Thread.Sleep(300)

Console.WriteLine("El subproceso {0} ha completado la
operación de escritura", _

tNombre)

rwl.ReleaseWriterLock()

End If

Next

End Sub

End Module


AUTORESETEVENT / MANUALRESETEVENT



Hay un Productor que realiza las acciones y un Consumidor que procesa los
resultados.


Un saludo,

Drk

"Pedro Ayensa" escribió en el mensaje
news:%
Hola,
estoy buscando la forma de implementar Monitores que no sean mutex. En mi
proyecto quiero que sólo se puedan crear simultáneamente X instancias de


una
clase, y el resto me gusaría que se quedaran a la espera de que alguna de
las creadas terminen su función. Había pensado que, como en UNIX, quizás
sería posible inicializar algún tipo de valor al número de instancias que
pueden crearse, y que cada vez que se creara una se decrementara hasta
llegar a 0, bloqueando a las sucesivas llamadas al constructor, pero sólo
encuentro el SyncLock.
¿Alguna idea que me pueda ayudar?
Gracias.


Respuesta Responder a este mensaje
#2 Tristan
10/08/2004 - 21:45 | Informe spam
¿Cada una de esas instancias correria en un subproceso propio?. Lo digo por
que si no, la aplicación se detendrá y nada podrá liberarla.

De todas formas, no tengo claro que no necesites semáforos. Parece más bien
que necesitas una clase singleton. Un caso concreto del patrón de singleton
aplicado a n instancias.

Una clase semáforo, como la que buscas sería algo así. Ojo!. No la he
probado demasiado.

Class Semaforo
Private contador As Integer
Private hiloSuspendido As Thread

Sub New(ByVal valor As Integer)
contador = valor
End Sub

Sub Wait()
Monitor.Enter(contador)
If contador = 0 Then
hiloSuspendido = Thread.CurrentThread
hiloSuspendido.Suspend()
Else
contador -= 1
End If
Monitor.Exit(contador)
End Sub

Sub Signal()
Monitor.Enter(contador)
If contador = 0 Then
hiloSuspendido.Resume()
End If
contador += 1
Monitor.Exit(contador)
End Sub
End Class

Juan Carlos Badiola
MVP - C#
Respuesta Responder a este mensaje
#3 Tristan
10/08/2004 - 22:37 | Informe spam
Pues no :-)

Me ha dado por pensar, y eso no puede funcionar. En lugar de Thread.Suspend,
utiliza un Mutex.Enter/Exit. Pero ten en cuenta que mutex impide entrar a la
región desde varios subprocesoso, pero permite entrar dos veces seguidas
desde el mismo subproceso.

Espero haberme explicado.

Juan Carlos Badiola
MVP - C#
Respuesta Responder a este mensaje
#4 Pedro Ayensa
11/08/2004 - 15:43 | Informe spam
OK, gracias a los dos por vuestras explicaciones. Estoy utilizando VB 2005
Beta y en esta versión aparece por primera vez el concepto de semaforo que
buscaba (System.Threading.Semaphore)
Gracias.

"Tristan" escribió en el mensaje
news:
Pues no :-)

Me ha dado por pensar, y eso no puede funcionar. En lugar de


Thread.Suspend,
utiliza un Mutex.Enter/Exit. Pero ten en cuenta que mutex impide entrar a


la
región desde varios subprocesoso, pero permite entrar dos veces seguidas
desde el mismo subproceso.

Espero haberme explicado.

Juan Carlos Badiola
MVP - C#


Respuesta Responder a este mensaje
#5 Tristan
11/08/2004 - 16:40 | Informe spam
Comprendo, pero en realidad n semáforo, no puede ser ni más ni menos que un
mutex con un contador, ¿no crees?

Pero bueno, si estás dispuesto a trabajar sobre una beta y ya tiene esa
clase, pues adelante.

Juan Carlos Badiola
MVP - C#
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida