2012-05-27 20 views
9

Estoy leyendo El lenguaje de programación D de Andrei Alexandrescu y encontró esta pepita en la secuencia de desmontaje:D: Destrucción garantizado

... D asume el salir de la aplicación se de facto liberar todos los recursos asociados con él, por lo que no invoca ningún destructor.

Esto funciona muy bien para recursos de memoria, pero ¿qué pasa con cosas como enchufes de red, hardware personalizado, manejadores de archivos, etc.? ¿Hay alguna forma de garantizar que mi destructor sea siempre llamado? Alternativamente: ¿D proporciona una mejor manera de manejar estas cosas (y estoy atrapado en una mentalidad de C++)?

+0

En ** C++ ** hay un escenario similar en caso de excepciones no controladas. –

+0

@ K-ballo: Correcto, pero durante la salida de la aplicación * normal *, no puedo garantizar que todos mis objetos sean destruidos. Esto es bastante inconveniente. –

+0

@TravisGockel ¿podría editar la pregunta para incluir el número de página? – Arlen

Respuesta

6

Puede utilizar un static destructor, que es llamada a la terminación del hilo y shared static destructor la que es llamada en el apagado (normal) la aplicación

(Ahora bien, si sólo tuviéramos referencias débiles, así que no necesita otro nivel de indirección. ..)

3

Otros han mencionado los destructores de nivel de módulo, pero eso no es realmente práctico ya que requiere demasiado mantenimiento manual, y D tiene una peculiaridad irritante si los módulos con constructores/destructores estáticos no pueden tener importaciones cíclicas. Por ejemplo:

Módulo A

module A; 
import B; 
static ~this() {} 
void main() {} 

Módulo B

module B; 
import A; 
static ~this() {} 

intenta ejecutar ...

% dmd A.d B.d 
% ./A 
Cycle detected between modules with ctors/dtors: 
A -> B -> A 
[email protected]/rt/minfo.d(331): Aborting! 

D hace esto en caso de que tus destructores dependan el uno del otro, incluso cuando no lo hagan. Esto te obliga a hacer una "refactorización" extraña de tu código para evitar este problema. No hay forma de decirle a D que no hay realmente una dependencia.

Una mejor solución para manejar la destrucción de recursos es tratar de abarcar tanto como sea posible. No tiene recursos globales que requieran destrucción, y no confíe en los finalizadores de clase para nada, porque no se garantiza que funcionen alguna vez (Java tiene el mismo problema).

Como alternativa, simplemente haga cosas como lo hacen en C: apagado manual. Es un poco más de trabajo, pero realmente no es un gran problema. Sin duda es más fácil que luchar con importaciones cíclicas.

0
  • Killing the processes limpia todo lo interno del proceso.
  • No hay forma de evitar que el sistema operativo mate un proceso antes de que tenga tiempo de limpiar cosas externas al proceso (y si lo hubiera, la pérdida de energía anularía incluso eso).

Entre los dos, todo está cubierto, por lo que no tiene sentido suponer que usted tiene algo que decir sobre cómo se apagan las cosas.