Aunque el método preferido en D para usar multihilo es apoyarse en datos
inmutables (mediante la palabra reservada immutable
) y sincronizar hilos
mediante paso de mensajes, el lenguaje soporta de forma nativa primitivas de
sincronización así como elementos que sirven para marcar objetos como
compartidos a los que se puede acceder desde múltiples hilos.
La palabra reservada shared
sirve para indicar que una variable va a ser
compartida entre múltiples hilos de ejecución diferentes:
shared(int)* p = new int;
int* t = p; // ERROR
Por ejemplo, la función std.concurrency.send
sólo permite enviar datos
marcados o con immutable
o con shared
, copiando el mensaje que se va a
enviar. La palabra reservada shared
es transitiva, es decir, si una clase
o un estructura se marcan con shared
, todos sus miembros serán marcados
de la misma forma. Hay que tener en cuenta que las variables estáticas (con
static
) no se comparten (con shared
) de forma predeterminada ya que la
implementación usa TLS (Thread Local Storage en inglés) y cada hilo de
ejecución tiene su propia copia.
Los bloques marcados con la palabra reservada synchronized
le indican al
compilador que dicho bloque es una sección crítica y que sólo un hilo de
ejecución puede acceder a ella al mismo tiempo.
synchronized {
importStuff();
}
Dentro de las funciones miembro de clases, estos bloques se pueden limitar a
objetos con exclusión mutua (mutexes en inglés) mediante
synchronized(member1, member2)
con el fin de reducir la contención. El
compilador de D inserta las secciones críticas de forma automática. Además,
se puede marcar una clase completa con synchronized
, con lo que el compilador
se asegurará de que sólo un hilo de ejecución al mismo tiempo tenga acceso
a una instancia concreta de dicha clase.
Se pueden usar operaciones atómicas en variables marcadas como shared
mediante la función core.atomic.atomicOp
:
shared int test = 5;
test.atomicOp!"+="(4);