2010-07-05 26 views
6

Me preguntaba si alguien sabe de una buena encuesta de técnicas de depuración para aplicaciones multiproceso. Idealmente, estoy buscando un análisis basado en casos: interbloqueos, inanición, estado compartido corrupto, ...Técnicas de depuración de subprocesos

.Net específico o genérico.

+6

Existen muchas herramientas geniales, pero no pase por alto el simple enfoque de simplemente leer el código. He estado haciendo depuración multihilo durante años, y es uno de los métodos más efectivos. –

+0

Es cierto. Eso funciona bastante bien. Estoy buscando más técnicas ('me gusta' esto) que herramientas. – Mau

+0

+1 @Stephen Muy cierto de hecho. –

Respuesta

11

No conozco un artículo o libro que aborde lo que está buscando, así que aquí están mis "lecciones aprendidas" de 12 años de depuración multiproceso en Windows (tanto no administrado como administrado).

Como mencioné en mi comentario, la mayor parte de mi "depuración multiproceso" se realiza realmente a través de una revisión de código manual, buscando estos problemas.

puntos muertos y dañado el estado compartido

Documento lock hierarchies (tanto en el orden y en qué estado se protegen compartida), y asegurarse de que son coherentes. Esto resuelve la mayoría de los problemas de interbloqueo y problemas de estado compartido corruptos.

(Nota: el enlace de arriba para "bloquear jerarquías" se refiere a un artículo del Dr. Dobbs por Herb Sutter, que ha escrito toda una serie de artículos Effective Concurrency que recomiendo).

Más sobre interbloqueos

Use RAII for all synchronization. Esto asegura que los bloqueos se lanzan frente a las excepciones. Prefiere la declaración de "bloqueo" para probar/finalmente.

(Tenga en cuenta que RAII en .NET depende de IDisposable, no Finalize, y se supone que el código de cliente usará correctamente un bloque using).

inanición

Retire cualquier modificación de las prioridades de rosca. La correcta priorización es en realidad un poco contra-intuitiva: es mejor dar al subproceso con más trabajo para hacer una prioridad más baja, y dar mayor prioridad a los hilos que están vinculados con E/S (incluido el subproceso de interfaz de usuario).Como Windows hace esto automáticamente (vea Windows Internals), realmente no hay ninguna razón para que el código se involucre en absoluto.

En general

eliminar todo el código de bloqueo sin que se escribió en el local. Es casi seguro que contiene errores sutiles. Reemplácelo con .NET 4 lock-free collections y synchronization objects, o cambie el código para que esté basado en el bloqueo.

Utilice conceptos de nivel superior para la sincronización. La casi cualquier necesidad Task Parallel Library y unified cancellation en .NET 4 Retire para el uso directo de la ManualResetEvent, Monitor, Semaphore, etc.

conceptos uso de más alto nivel para la paralelización. El TPL and PLINQ en .NET 4 tiene algoritmos de autoequilibrado integrados con particiones inteligentes y colas de robo de trabajo para proporcionar una paralelización óptima de forma automática. Para los pocos casos en que la paralelización automática no es óptima, tanto TPL como PLINQ exponen una gran cantidad de perillas ajustables (esquemas de particionamiento personalizados, indicadores de operación de larga ejecución, etc.).

Hay una técnica más que he encontrado útil para cualquier clase que tiene sus métodos llamados por diferentes subprocesos: documentar qué métodos se ejecutan en qué subprocesos. Por lo general, esto se agrega como un comentario en la parte superior del método. Asegúrese de que cada método solo se ejecute en un contexto de subproceso conocido (por ejemplo, "en un subproceso de UI" o "en un subproceso de ThreadPool" o "en el subproceso de fondo dedicado"). Ninguno de los métodos debe decir "en ningún hilo" a menos que esté escribiendo una clase de sincronización (y si está escribiendo una clase de sincronización, pregúntese si realmente debería estar haciendo eso).

Por último, nombre sus hilos. Esto ayuda a distinguirlos fácilmente cuando se utiliza el depurador VS. .NET admite esto a través de la propiedad .

6

No es lo que está pidiendo, pero tal vez encuentre CHESS interesante.

+0

Interesante, gracias. – Mau

+0

+1 por ... genialidad. ¡No tenía idea de que existiera tal cosa! viva AJEDREZ! –

+0

Eso es realmente increíble. –

0

He usado Helgrind a subtool de Valgrind. Helgrind es un detector de errores de hilo y lo he usado una o dos veces para detectar condiciones de carrera en algunos de mis códigos. Puede detectar las siguientes cosas.

  1. Malos usos de la API POSIX pthreads.
  2. Posibles bloqueos debidos a problemas de bloqueo de pedidos.
  3. Razas de datos: acceso a la memoria sin un bloqueo o sincronización adecuados.

http://valgrind.org/docs/manual/hg-manual.html

Obviamente única herramienta para los programas del sistema Linux, C/C++. Sin Java o .NET.

0

No creo que ninguna técnica pueda detectar con fiabilidad todos los problemas de subprocesos múltiples, porque el código que los causa es demasiado complicado de analizar. Ninguna herramienta puede detectar dichos problemas en tiempo real, porque la herramienta en sí misma también necesita tiempo para ejecutarse. El programa para depurar se comportaría completamente diferente con la herramienta y sin ella.

Tuve que solucionar problemas de tiempo real que ocurrieron en la producción solo una vez al mes. La única solución que encontré es agregar código detectando ese problema y escribir información de rastreo por los hilos involucrados. Por supuesto, el trazado debe ser EXTREMADAMENTE rápido y no bloquear. herramientas habituales, como Visual Studio son demasiado lento para el tiempo real de la localización, pero por suerte, es fácil de escribir su propia huella de la memoria:

const int maxMessages = 0x100; 
const int indexMask = maxMessages-1; 
string[] messages = new string[maxMessages]; 
int messagesIndex = -1; 

public void Trace(string message) { 
    int thisIndex = Interlocked.Increment(ref messagesIndex) & indexMask; 
    messages[thisIndex] = message; 
} 

Una descripción más detallada de este enfoque, que además contiene información y salidas de rosca y el momento la traza está muy bien en: CodeProject: depuración de código multiproceso en tiempo real 1

Cuestiones relacionadas