none
Duda sobre concurrencia en la que un proceso debe esperar al que resto acabe.

    Question

  • Por un lado tengo varios hilos que acceden a partes con:
    lock(objeto){
       [...]
    }

    y por otro tengo:
    objetoB = objeto;
    objeto = nuevo objeto;
    lock(objetoB){
       [Parte que podría tardar bastante]
    }

    Como puede observarse en un momento dado cambio el objeto a uno nuevo para que a partir de ese momento los hilos se bloqueen con otro objeto, y uso el antiguo para esta parte, en realidad lo que me gustaría es que no se entre en la "parte que podría tardar bastante" hasta asegurarme de que no hay ningun hilo esperando usando el objeto antiguo.

    ¿Que me recomendais?

    Gracias de antemano.


    PD: Si se va dejando pasar a los hilos en el orden que llegaron al lock supongo que no habrá problema como lo tengo (porque una vez el hilo especial llega a lock(objetoB) ya se ha cambiado el objeto y los que lleguen al lock lo haran con el objeto nuevo). Pero no veo en ningun sitio si se deja pasar en orden o al azar :S.

    • Edited by BlackCid Tuesday, February 14, 2012 1:34 PM
    Tuesday, February 14, 2012 1:27 PM

Answers

  • Hola BlackCid,

    Cuando hablamos de "sincronizar" varios hilos, se usa la llamada programación concurrente. Para esto puedes usar herramientas específicas como semaforos y monitores (Semaphore y Monitor).

    En este caso, creo que con un Semaphore de .net te puede servir. Ya que puedes crear un sistema de gestión concurrente de tantos hilos como desees:

    Tiene un estado inicial:

    var semaphore = new Semaphore(0, 5); // para gestionar 5 hilos con un estado inicial apagado

    Puedes mandar señal de release para que entre en juego el siguiente:

    semaphore.Release();

    O puedes mantenerte a la espera:

    semaphonre.WaitOne();

    Lo mejor es leer la documentación de MSDN que está muy bien explicada:

    http://msdn.microsoft.com/es-es/library/system.threading.semaphore(v=vs.80).aspx


    Fernanando Escolar - http://www.programandonet.com/ - @fernandoescolar

    Tuesday, February 14, 2012 3:15 PM
  • hola

    Part 2: Basic Synchronization

    tienes una teaoria bien extensa sobre como trabajar con thread y los lock

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    Tuesday, February 14, 2012 3:29 PM

All replies

  • uso el antiguo para esta parte, en realidad lo que me gustaría es que no se entre en la "parte que podría tardar bastante" hasta asegurarme de que no hay ningun hilo esperando usando el objeto antiguo.

    el tema es que tu no controlas ese aspecto

    alli defines un bloque de codigo que evita la concurrencia en dodne varios hilos podrian acceder

    si uno llega a esa parte del codigo eejcutara menteniendo bloqueado al resto hasta que ese termine, pero si el resto de lso hilos que lanzas requieren de ese codigo es logico que pasaran por alli tambien

    no entiendo que sentido tendria que los demas hilos conozcan que ese bloque de codigo lo usa otro hilo y lo pasen por alto

    quizas el priemr hilo que ingresa podria poner algun flag indicando que esta alli ejecutando y los demas evaluen ese flag para no ingresar, pero lo veo algo extraño

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    Tuesday, February 14, 2012 1:41 PM
  • Hola.

    Quiza si nos cuentas cual es el objetivo de hacer todo esto, podamos darte mas puntos de vista y quiza una solucion mas optima al problema.

    Saludos.


    Nicolás Herrera
    Bogotá - Colombia
    BLOG - Leader Group BogotaDotNet
    "Daría todo lo que sé, por la mitad de lo que ignoro." Rene Descartes

    Tuesday, February 14, 2012 2:01 PM
  • A ver la idea es la siguiente, tengo un "recurso" que no es thread safe, y para hacer uso de el debo bloquear con locks, el tema es que cada X tiempo se empieza a usar un recurso nuevo mientras el antiguo se usa solo para una última cosa (en paralelo), esto último tarda mucho, y mientras me gustaría que fueran usando el recurso nuevo, por ello quiero evitar que se empiece a hacer esta parte larga hasta que el resto de hilos deje de esperar por el recurso antiguo.

    No se si se entiende, simplemente es evitar que se empiece el proceso largo si hay algun hilo atascado en un lock que usa el objeto antiguo. Por eso decía que si se sirven de manera consecutiva no habrá problema (ya que cuando el proceso largo llega al lock ha realizado el cambio al objeto nuevo y por tanto los que lleguen a un lock despues de el usaran el nuevo).

    Gracias por contestar.

    PD: He leido buscando por el foro que los lock se sirven en orden, ¿me lo podeis confirmar? Si es asi me funcionará perfectamente lo que tengo hecho.
    • Edited by BlackCid Tuesday, February 14, 2012 2:27 PM
    Tuesday, February 14, 2012 2:18 PM
  • Hola BlackCid,

    Cuando hablamos de "sincronizar" varios hilos, se usa la llamada programación concurrente. Para esto puedes usar herramientas específicas como semaforos y monitores (Semaphore y Monitor).

    En este caso, creo que con un Semaphore de .net te puede servir. Ya que puedes crear un sistema de gestión concurrente de tantos hilos como desees:

    Tiene un estado inicial:

    var semaphore = new Semaphore(0, 5); // para gestionar 5 hilos con un estado inicial apagado

    Puedes mandar señal de release para que entre en juego el siguiente:

    semaphore.Release();

    O puedes mantenerte a la espera:

    semaphonre.WaitOne();

    Lo mejor es leer la documentación de MSDN que está muy bien explicada:

    http://msdn.microsoft.com/es-es/library/system.threading.semaphore(v=vs.80).aspx


    Fernanando Escolar - http://www.programandonet.com/ - @fernandoescolar

    Tuesday, February 14, 2012 3:15 PM
  • hola

    Part 2: Basic Synchronization

    tienes una teaoria bien extensa sobre como trabajar con thread y los lock

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    Tuesday, February 14, 2012 3:29 PM
  • Me parece una información muy interesante...

    Solo le veo un pero al uso de locks, que es que corres el peligro de dejar "pinzado" (freeze o como se quiera llamar) al proceso, ya que no tiene ningún método de seguridad. En ese supuesto en mi humilde opinión creo que es más seguro un Monitor.Wait(objeto, TimeSpan), ya que si se cumple un tiempo mínimo de espera lanzará la excepción (Timeout) y no bloquerá nunca los hilos...

    Un poco el resumen es que un lock es un bloque exclusivo hasta que no se libere... y esto tiene implicaciones de que podría darse el caso de ser "para siempre", si se gestiona de una forma diferente a la que está pensado.

    De todas formas, visto el enlace de Leandro, hay que decidir si "lock" (Monitor.Wait(obj, ts)) es verdaderamente útil en el escenario que planteas o necesitas algo más de funcionalidad (como la de un semaphore) para tratar un escenario de programación concurrente en la que varios hilos están realizando diferentes tareas al mismo tiempo y requieres varias exclusiones mutuas...



    Fernanando Escolar - http://www.programandonet.com/ - @fernandoescolar

    Tuesday, February 14, 2012 3:44 PM