Este artículo es un artículo espejo de traducción automática, por favor haga clic aquí para saltar al artículo original.

Vista: 46741|Respuesta: 7

[Fuente] Volátil vs. Interlock vs. bloqueo

[Copiar enlace]
Publicado en 27/8/2018 14:40:35 | | |
Supongamos que hay una clase que contiene un campo contador público de int al que pueden acceder múltiples hilos, y este número solo aumentará o disminuirá.

Al añadir este campo, ¿cuál de los siguientes esquemas debería usarse y por qué?

  • lock(this.locker) this.counter++;
  • Interlocked.Increment(ref this.counter);
  • Cambiar el modificador de acceso de contador a volátil público


Peor (ninguna de ellas funciona realmente)

Cambiar el modificador de acceso de contador a volátil público

Este enfoque en realidad no es seguro en absoluto, y la cuestión de Volátil es que múltiples hilos ejecutándose en múltiples CPUs almacenan los datos en búfer y reorganizan las instrucciones ejecutadas.

Si es no volátil, cuando la CPU A aumenta un valor, la CPU B necesita esperar un tiempo para ver el valor incrementado, lo que puede causar problemas.

Si es volátil, asegura que ambas CPUs vean el mismo valor al mismo tiempo. Pero no evita las operaciones de lectura y escritura transversales.

Añadir valor a una variable en realidad requiere tres pasos

1. Lectura, 2. Añadir 3. Escribir

Supongamos que el hilo A lee el valor del contador como 1 y no está listo para aumentar, entonces el hilo B también lee el valor del contador como 1, y ambos hilos comienzan a realizar operaciones incrementales y de escritura. El valor de la ficha final es 2. Esto no es correcto, ambos hilos han realizado una operación de aumento, y el resultado correcto debería ser 3. Así que etiquetarlo como volátil es simplemente inseguro.

Es mejor

lock(this.locker) this.counter++;

Así es seguro (recuerda cerrar con llave todos los sitios donde quieras acceder a este mostrador, por supuesto). Evita que cualquier otro hilo ejecute el código bloqueado. Y también previene el problema de secuenciación de instrucciones multi-CPU mencionado anteriormente. El problema es que el bloqueo es lento en rendimiento, y si usas bloqueo en otros lugares no relacionados, puede bloquear los otros hilos.

Lo mejor

Interlocked.Increment(ref this.counter);

Esto es seguro y muy eficiente. Realiza lectura, aumento y escritura de tres operaciones en un mismo átomo sin ser interrumpido en el centro. Como no afecta a otros códigos, no necesitas recordar cerraduras en otros sitios. Y además es muy rápido (como dice MSDN, en las CPUs actuales suele ser solo una instrucción).

Pero no estoy del todo seguro de si también puede resolver el problema de ordenación de instrucciones de la CPU, o si debe usarse junto con volátil y este incremento.

Suplemento: ¿Qué problemas resuelve bien el volátil?

Como el volátil no puede evitar el multihilo, ¿qué puede hacer? Un buen ejemplo es que tienes dos hilos, uno siempre escribe en una variable, digamos que esta variable es queneLength, y el otro siempre lee datos de esta variable. Si la longitud de la cola no es volátil, el hilo A puede leerse 5 veces, pero el hilo B puede ver datos retrasados, o incluso datos en orden incorrecto. Una solución es usar bloqueo, pero en este caso también puedes usar volátil. Esto asegura que el hilo B siempre vea los datos más recientes escritos por el hilo A, pero esta lógica solo funciona si no lo lees al escribirlo, y si no lo escribes al leerlo. Cuando varios hilos quieren realizar operaciones de lectura, modificación y escritura, necesitas usar Interlock o bloqueo.





Anterior:Método de cifrado Java MD5
Próximo:Linq implementa consultas condicionales en y no en SQL
Publicado en 29/8/2018 16:21:42 |
Hola, ¿el código que hiciste antes que combina histogramas apilados de altos gráficos y histogramas perforables? Me gustaría preguntar si puedes enviar un código que se pueda editar en la interfaz https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light.
Publicado en 29/8/2018 16:22:13 |
Toda la red es solo tu recurso.
Publicado en 29/8/2018 16:22:55 |
Porque los anteriores 90 años no podían dejar un mensaje. así que
Publicado en 29/8/2018 16:40:40 |
¿Es conveniente añadir una información de contacto? Consultaremos contigo
 Propietario| Publicado en 15/9/2018 13:10:16 |
private static int safeInstanceCount = 0; Operar con átomos
System.Threading.Interlocked.Increment(ref safeInstanceCount); Auto-aumento 1
System.Threading.Interlocked.Decrement(ref safeInstanceCount); Auto-menos 1
Publicado en 21/5/2020 16:43:54 |
Apoya al propietario para que comparta
 Propietario| Publicado en 11/6/2020 15:00:16 |
1. Concepto

En un entorno multihilo, operaciones que no son interrumpidas por mecanismos de planificación de hilos; Una vez que comienza esta operación, se ejecuta hasta el final, sin ningún cambio de contexto (cambiar a otro hilo) entre medias.

2. Clase

Clase estática System.Threading.Interlocked

3. Funciones comúnmente usadas (véase el resto)

1. estática pública int Disminución (ref int ubicación); Reduce el valor de la variable especificada en forma de operación atómica y almacena el resultado

Equivalente a la cerradura(obj){i--; }

2. estática pública int Increment(ubicación de ref int); Incrementa el valor de la variable especificada en forma de operación atómica y almacena el resultado

Equivalente a lock(obj){i++; }
Renuncia:
Todo el software, materiales de programación o artículos publicados por Code Farmer Network son únicamente para fines de aprendizaje e investigación; El contenido anterior no se utilizará con fines comerciales o ilegales; de lo contrario, los usuarios asumirán todas las consecuencias. La información de este sitio proviene de Internet, y las disputas de derechos de autor no tienen nada que ver con este sitio. Debes eliminar completamente el contenido anterior de tu ordenador en un plazo de 24 horas desde la descarga. Si te gusta el programa, por favor apoya el software genuino, compra el registro y obtén mejores servicios genuinos. Si hay alguna infracción, por favor contáctanos por correo electrónico.

Mail To:help@itsvse.com