multithreading - En Delphi, ¿es seguro el subproceso OutputDebugString?
delphi-7 (3)
Bueno, no es que no sea cierto, lo es, sino solo para que no tengas que aceptar la palabra de Lieven:
El paso de datos entre la aplicación y el depurador se realiza a través de un trozo de memoria compartida de 4kbyte, con un objeto Mutex y dos objetos de evento que protegen el acceso al mismo. Estos son los cuatro objetos kernel involucrados.
Comprender Win32 OutputDebugString es un excelente artículo sobre el tema.
Es
OutputDebugString(PAnsiChar(''''));
¿a salvo de amenazas?
Lo he estado usando en hilos para la depuración, y nunca se me ocurrió si debería hacerlo de otra manera.
(Delphi 7)
No te preocupes, lo es.
Cuando una aplicación llama a OutputDebugString (), sigue estos pasos. Tenga en cuenta que una falla en cualquier punto abandona todo y trata la solicitud de depuración como no operativa (la cadena no se envía a ninguna parte).
- Abra DBWinMutex y espere hasta que tengamos acceso exclusivo a él.
- Asigne el segmento DBWIN_BUFFER a la memoria: si no se encuentra, no hay un depurador ejecutándose, por lo que se ignora toda la solicitud.
- Abra los eventos DBWIN_BUFFER_READY y DBWIN_DATA_READY. Al igual que con el segmento de memoria compartida, los objetos faltantes significan que no hay ningún depurador disponible.
- Espere a que se señale el evento DBWIN_BUFFER_READY: esto indica que el búfer de memoria ya no está en uso. La mayoría de las veces, este evento se señalará inmediatamente cuando se examine, pero no esperará más de 10 segundos para que el búfer esté listo (un tiempo de espera abandona la solicitud).
- Copie hasta 4kbytes de datos en el búfer de memoria y también almacene el ID del proceso actual allí. Siempre coloque un byte NUL al final de la cadena.
- Indique al depurador que el búfer está listo estableciendo el evento DBWIN_DATA_READY. El depurador lo toma de allí.
- Libera el mutex
- Cierra los objetos Evento y Sección, aunque mantenemos el control del mutex para más adelante.
Sin embargo, he tenido problemas una vez con cadenas en una DLL ISAPI. Por algún extraño motivo, no se configuró el booleano IsMultiThread definido en System.pas.
Estaba causando AccessViolations extraño, una vez que el hilo estaba ejecutando más de un hilo ... Un simple "IsMultiThread: = true;" en una unidad de inicialización lo arregló.