Haz tus hilos lo más simple posible.
Trate de no utilizar las variables globales. Las constantes globales (constantes reales que nunca cambian) están bien. Cuando necesite usar variables globales o compartidas, debe protegerlas con algún tipo de mutex/lock (semáforo, monitor, ...).
Asegúrese de que realmente entiende cómo funcionan sus mutexes. Hay algunas implementaciones diferentes que pueden funcionar de manera diferente.
Trate de organizar su código para que las secciones críticas (lugares donde tiene algún tipo de cerrojo (s)) sean lo más rápido posible. Tenga en cuenta que algunas funciones pueden bloquear (suspender o esperar algo y evitar que el sistema operativo permita que ese hilo continúe ejecutándose durante un tiempo). No los use mientras mantiene bloqueos (a menos que sea absolutamente necesario o durante la depuración ya que a veces puede mostrar otros errores).
Trate de entender lo que más hilos de hecho hace por usted.A ciegas, lanzar más hilos a un problema muy a menudo empeorará las cosas. Diferentes hilos compiten por la CPU y por los bloqueos.
La evasión de interbloqueo requiere planificación. Intente evitar tener que adquirir más de un bloqueo a la vez. Si esto es inevitable, decida un pedido que utilizará para adquirir y liberar los bloqueos de todos los hilos. Asegúrate de saber qué significa un punto muerto.
La depuración de aplicaciones multiproceso o distribuidas es difícil. Si puede hacer la mayor parte de la depuración en un único entorno con hebras (tal vez incluso forzando a que otros subprocesos duerman), entonces puede intentar eliminar los errores céntricos que no son de subprocesamiento antes de saltar a la depuración de subprocesos múltiples.
Siempre piense en lo que los otros hilos podrían estar haciendo. Comenta esto en tu código. Si está haciendo algo de cierta manera porque sabe que en ese momento no debería haber ningún otro subproceso que esté accediendo a un determinado recurso, escriba un comentario importante que lo diga.
Es posible que desee para envolver las llamadas a los bloqueos mutex/desbloquea en otras funciones como:
int my_lock_get (bloqueo lock_type, archivo * const char, línea, const char * msg) {
thread_id_type me = this_thread();
logf("%u\t%s (%u)\t%s:%u\t%s\t%s\n", time_now(), thread_name(me), me, "get", msg);
lock_get(lock);
logf("%u\t%s (%u)\t%s:%u\t%s\t%s\n", time_now(), thread_name(me), me, "in", msg);
}
Y una versión similar para desbloquear. Tenga en cuenta que las funciones y los tipos utilizados en este conjunto están compuestos y no están basados excesivamente en ninguna API.
Usando algo como esto puede volver si hay un error y usar un script perl o algo similar para ejecutar consultas en sus registros para examinar dónde salieron las cosas (cerraduras y desbloqueos correspondientes, por ejemplo).
Tenga en cuenta que su funcionalidad de impresión o registro puede necesitar bloqueos también. Muchas bibliotecas ya tienen esto integrado, pero no todas lo hacen. Estos bloqueos no necesitan utilizar la versión de impresión de las funciones lock_ [get | release] o tendrá recursión infinita.
Muchas gracias Pero, ¿cómo resolver estos problemas? – brett
Todos estos problemas se pueden resolver con semáforos (bloqueos). Necesita comprender cuidadosamente lo que está haciendo primero. Trate de no sobrepasarlo con hilos, son una herramienta para ayudar a su programa a hacer cosas, no un truco mágico que necesita poner en todo el lugar – Eric