7

Necesito ayuda para entender sincronizaciones-con relación. Cuanto más lo estoy leyendo y tratando de entender el ejemplo, más siento que no entiendo nada. A veces siento que aquí está, lo tengo, pero después de mirar otro ejemplo, me confundo nuevamente. Por favor, ayúdame a hacerlo bien.synchronisms-with, happens-before relation y acquire-release semántica

Se dice que una operación A se sincroniza: con una operación B si A es un almacén para alguna variable atómica m, con semántica de liberación, B es una carga de la misma variable m, con semántica de adquisición y B lee el valor almacenada por A. también se dice que una operación a sucede-antes de una operación B si

  • a se realiza en el mismo hilo como B, y a es antes de B en el orden del programa, o
  • a sincroniza -with B, o
  • A sucede antes de otra operación C y C sucede antes de B

OK. Si miramos este ejemplo

thread0 realiza | Thread1 realiza


tienda de x (liberación) | cargar x (adquirir)

¿almacenar en x aquí sincronizar-con la carga de x? Si tenemos sincronizaciones -con relación aquí, entonces almacenar en x ocurre antes de cargar desde x, entonces todo lo que se secuencia antes de almacenar en x en el hilo 0 ocurre -antes de cargar desde x en el hilo 1. Esto significa que hay ordenamiento forzado aquí. ¿Es correcto? Pero en este caso, no entiendo qué significa "y B lee el valor almacenado por A", parte de la definición significa? Si el hilo 1 es más rápido que el hilo 0, puede leer el valor anterior. Entonces, ¿cuál es la relación aquí y hay alguna relación? Si no hay, ¿cómo puedo proporcionar esa relación?

Gracias de antemano.

+0

un gran artículo está aquí http://preshing.com/20130823/the-synchronizes-with-relation/ – camino

Respuesta

4

No puedo decir que esté familiarizado con la terminología, pero así es como creo que va. Utilizaré las definiciones de .NET para los términos: "Una operación tiene semántica de adquisición si otros procesadores verán siempre su efecto antes del efecto de cualquier operación subsiguiente. Una operación tiene semántica de liberación si otros procesadores verán el efecto de cada operación anterior antes del efecto del operación en sí. "

No hay ordenamiento obligatorio entre la tienda y la carga en el ejemplo. Cualquiera de los dos puede ejecutarse primero. A sincroniza: con B cuando la operación de almacenamiento se ejecuta antes de la carga. Cuando esto sucede, se garantiza que todas las operaciones antes de la tienda (lanzamiento) se ejecutarán antes de las operaciones después de que se ejecute la carga (adquisición).

Sin embargo, la operación de carga se puede ejecutar antes de la tienda. En ese caso, A no sincroniza -con B (ya que la condición "y B lee el valor almacenado por A" no es verdadero) y entonces las operaciones después de la carga pueden ejecutarse antes de las operaciones que preceden a la tienda. El orden es vago

La semántica de liberación garantiza que para cierto valor de x sabremos que las operaciones que preceden a la tienda se ejecutarán antes de que podamos cargar el mismo valor almacenado en la segunda cadena (y antes de que podamos ejecutar las operaciones siguiendo la carga).

Vamos a suponer que el recuento y la bandera se inicializan a cero y ambos hilos se ejecutan en paralelo:

thread0: 
st   count, 1 (A) 
st.release flag, 1 (B) 

thread1: 
ld.acquire flag  (C) 
ld   count  (D) 

sabemos que un pasa-antes de que B y C sucede antes D, ya que su fin es forzado por la semántica de lanzamiento y adquisición. El orden de B y C no está definido. Solo se define cuando B se sincroniza, con C y luego sabemos que A sucede, antes de D (como sucede A, antes de que B suceda, antes de que C suceda, antes de D).

En thread1 el recuento es siempre 1 si el indicador es 1. Si el indicador es 0 el recuento puede ser 0 o 1. Podríamos probar el indicador para determinar si el otro hilo ha establecido el valor del recuento.

Sin semántica de adquisición y liberación, las cargas y los almacenes podrían reordenarse y tanto el indicador como el conteo podrían ser 0 o 1 sin dependencia entre ellos.

Si queremos asegurarnos de que B suceda, antes de C, podemos usar semáforos o algún otro mecanismo de espera y señal. En el ejemplo anterior, podríamos hacer cumplir la orden por ocupado, esperando que se establezca la bandera.

thread1: 
ld.acquire flag  (C) 
repeat C while flag == 0 
ld   count  (D)