2009-12-28 15 views
70

¿Puede alguien explicar por favor simplemente qué es la contención del hilo?¿Qué es la contención de hilos?

Lo he buscado en Google, pero no puedo encontrar una explicación simple.

+6

Así que escriba cuál es su pensamiento vago sobre él, para que podamos ver dónde puede estar, o su comprensión puede ser correcta. –

Respuesta

56

Básicamente la contención de hilos es una condición en la que un hilo está esperando un bloqueo/objeto que está siendo retenido por otro hilo. Por lo tanto, este hilo de espera no puede usar ese objeto hasta que el otro hilo haya desbloqueado ese objeto en particular.

+30

Esta respuesta es incompleta (como la mayoría de las demás). Mientras que un bloqueo es un tipo de cosa sobre la que puede haber una disputa, está lejos de ser la única cosa así. También puede haber contención por los recursos sin cerradura. (Por ejemplo, si dos subprocesos continúan aumentando atómicamente el mismo número entero, pueden experimentar contención debido al ping-ponging de la memoria caché. No hay bloqueos involucrados.) –

+0

En el caso de un bloqueo de intérprete global (GIL) como en CPython, donde el hilo siempre debe adquirir el GIL, por lo tanto, múltiples hilos que se ejecutan en el mismo proceso están en disputa por defecto. –

+0

Creo que lo has explicado en términos de punto muerto, pero es muy diferente del punto muerto. –

1

Otra palabra podría ser concurrencia. Es simplemente la idea de que dos o más hilos intenten usar el mismo recurso.

2

Tiene 2 hilos. Subproceso A y subproceso B, también tiene el objeto C.

A está accediendo al objeto C y ha colocado un bloqueo en ese objeto. B necesita acceder objeto C, pero no puede hacerlo hasta que A libera el bloqueo en el objeto C.

16

De here:

A contención se produce cuando un hilo es espera de un recurso que no es fácilmente disponibles; ralentiza la ejecución de su código , pero puede borrar con el tiempo.

se produce un interbloqueo cuando un hilo es esperando por un recurso que un segundo mensaje ha bloqueado, y el segundo hilo está esperando por un recurso que el primer hilo ha bloqueado. Más de dos hilos pueden estar involucrados en un punto muerto . Un punto muerto nunca se resuelve sí mismo. A menudo hace que la aplicación completa , o la parte que está experimentando el interbloqueo, se detenga.

+0

Esto también explica la diferencia entre thread Contention y Deadlock – Sankalp

125

Varias respuestas parecen centrarse en la contención del bloqueo, pero los bloqueos no son los únicos recursos en los que se puede experimentar la contención. La contención es simplemente cuando dos hilos intentan acceder al mismo recurso o recursos relacionados de tal manera que al menos uno de los hilos contendientes se ejecuta más lentamente de lo que lo haría si el otro hilo (s) no se ejecuta.

El ejemplo más obvio de contención es en un candado. Si el hilo A tiene un bloqueo y el hilo B quiere adquirir el mismo bloqueo, el hilo B tendrá que esperar hasta que el hilo A libere el bloqueo.

Ahora, esto es específico de la plataforma, pero el hilo puede experimentar ralentizaciones incluso si no tiene que esperar a que el otro hilo libere el bloqueo. Esto se debe a que un bloqueo protege algún tipo de datos y, a menudo, también se contestarán los mismos datos.

Por ejemplo, considere un hilo que adquiere un bloqueo, modifica un objeto, luego libera el bloqueo y hace otras cosas. Si dos subprocesos hacen esto, incluso si nunca luchan por el bloqueo, los subprocesos pueden ejecutarse mucho más lentamente de lo que lo harían si solo se ejecutara un subproceso.

¿Por qué? Supongamos que cada subproceso se ejecuta en su propio núcleo en una CPU x86 moderna y los núcleos no comparten una memoria caché L2. Con solo un hilo, el objeto puede permanecer en el caché L2 la mayor parte del tiempo. Con ambos subprocesos en ejecución, cada vez que un subproceso modifica el objeto, el otro subproceso encontrará que los datos no están en su caché L2 porque la otra CPU invalidó la línea de caché.En un Pentium D, por ejemplo, esto hará que el código se ejecute a la velocidad del FSB, que es mucho menor que la velocidad de caché L2.

Dado que puede producirse una disputa incluso si el bloqueo no se disputa por sí mismo, la contención también puede ocurrir cuando no hay un bloqueo. Por ejemplo, supongamos que su CPU admite un incremento atómico de una variable de 32 bits. Si un hilo sigue incrementando y disminuyendo una variable, la variable estará caliente en el caché la mayor parte del tiempo. Si dos subprocesos lo hacen, sus cach contienden por la propiedad de la memoria que contiene esa variable, y muchos accesos serán más lentos a medida que el protocolo de coherencia de caché opera para asegurar cada propiedad central de la línea de caché.

Irónicamente, los bloqueos normalmente reducen contention. ¿Por qué? Porque sin un bloqueo, dos subprocesos podrían operar en el mismo objeto o colección y causar mucha contención (por ejemplo, hay colas sin bloqueo). Los bloqueos tenderán a desprogramar subprocesos contendientes, permitiendo que se ejecuten subprocesos no contendientes en su lugar. Si el hilo A contiene un bloqueo y el hilo B quiere el mismo bloqueo, la implementación puede ejecutar el hilo C en su lugar. Si el hilo C no necesita ese bloqueo, la contención futura entre los hilos A y B puede evitarse por un tiempo. (Por supuesto, esto supone que hay otros subprocesos que podrían ejecutarse. No ayudará si la única forma en que el sistema en su conjunto puede hacer progreso útil es ejecutando hilos que contengan).

+2

+1 Además, solo para hacer esto explícito, las dos variables por las cuales dos núcleos están peleando ni siquiera necesitan ser la misma variable para causar contención, solo tienen que almacenarse en memoria en la misma línea de caché. Rellenar estructuras y/o alinear estructuras a la memoria puede ayudar a evitar esta forma de contención. –

+1

@David, por favor ayuda a comprender el último párrafo de tu respuesta con más detalle –

+3

@Naroji Haz una pregunta al respecto. –

1

Para mí, la competencia es una competencia entre 2 o más hilos sobre un recurso compartido. El recurso puede ser un candado, un mostrador, etc. La competencia significa "quién la obtiene primero". Cuantos más hilos, más contención. Cuanto más frecuente es el acceso a un recurso, más contención.

2

Creo que debería haber alguna aclaración por parte de la OP en el fondo de la cuestión - se me ocurre 2 respuestas (aunque estoy seguro de que hay adiciones a esta lista):

  1. si se están refiriendo al "concepto" general de contención de hilos y cómo puede presentarse en una aplicación, difiero a la respuesta detallada de @DavidSchwartz anterior.

  2. También está el contador de rendimiento '.NET CLR Locks and Threads: Total # of Contentions'. Según se toma de la descripción de PerfMon para este contador, se define como:

    Este contador muestra el número total de veces que los hilos en el CLR han intentado adquirir un bloqueo administrado sin éxito. Los bloqueos administrados se pueden adquirir de muchas maneras; por la instrucción "lock" en C# o llamando a System.Monitor.Enter o usando MethodImplOptions. Atributo personalizado sincronizado.

... y estoy seguro que otros para otros Sistemas Operativos y los entornos de aplicaciones.

0

La contención de subprocesos también se ve afectada por las operaciones de E/S. Ejemplo cuando un hilo que espera la lectura del archivo puede considerarse una disputa. Use los puertos de terminación de E/S como solución.

0

La contención de bloqueo tiene lugar cuando un hilo intenta adquirir el bloqueo a un objeto que ya ha sido adquirido por otro hilo *. Hasta que se libere el objeto , el hilo está bloqueado (en otras palabras, está en el estado de espera ). En algunos casos, esto puede llevar a la llamada ejecución serial que afecta negativamente a la aplicación.

de dotTrace documentation

0

Imagine el siguiente escenario. Te estás preparando para el examen final de mañana y te sientes un poco hambriento. Entonces, le das a tu hermano menor diez dólares y le pides que compre una pizza para ti. En este caso, usted es el hilo principal y su hermano es un hilo hijo. Una vez que su pedido es dado, tanto usted como su hermano están haciendo su trabajo al mismo tiempo (es decir, estudiando y comprando una pizza). Ahora, tenemos dos casos para considerar . Primero, su hermano le devuelve la pizza y termina el mientras estudia. En este caso, puede dejar de estudiar y disfrutar de la pizza . En segundo lugar, termina su estudio temprano y duerme (es decir, su trabajo asignado para hoy - se realiza el estudio para el examen final de mañana) antes de que la pizza esté disponible. Por supuesto, no puedes dormir; de lo contrario, no tendrá la oportunidad de comer la pizza. Lo que va a hacer es para esperar hasta que su hermano le devuelva la pizza.

Como en el ejemplo, los dos casos dan un significado de rivalidad.

Cuestiones relacionadas