En Rust, las variables globales se declaran utilizando la palabra clave static. Estas variables viven durante toda la ejecución del programa. Por defecto, el acceso a static inmutable es seguro, pero para static mutables se requiere usar unsafe, ya que el compilador no puede garantizar la ausencia de condiciones de carrera.
Para el acceso seguro a las variables globales mutables, se utilizan tipos de envoltura especiales: Mutex, RwLock, tipos Atomic* o crates externos (lazy_static, once_cell). La inicialización es "perezosa", si se requiere la creación diferida del objeto en el primer acceso.
Ejemplos:
static COUNTER: AtomicUsize = AtomicUsize::new(0); static ref CONFIG: Config = read_config(); // utilizando lazy_static o once_cell
¿Se puede declarar una variable global mutable sin tipos especiales, si solo se usará desde un solo hilo? ¿Es necesario escribir unsafe?
Respuesta:
El compilador requerirá el uso de unsafe en cualquier modificación de una variable global, incluso si la lógica es de un solo hilo. Este es un requisito general para todos los static mut. Solo si la variable está envuelta en una estructura de sincronización (Mutex, atómico, etc.), el compilador permitirá el acceso seguro.
static mut VALUE: i32 = 0; unsafe { VALUE += 1; }
Historia
En un servicio web, al inicializar una caché global se utilizó una variable static normal con una cadena. Varios hilos escribían en ella simultáneamente, causando "bytes" de memoria y caídas de la aplicación debido a la carrera de hilos.
Historia
En una utilidad de línea de comandos en Rust, se modificó una variable estática sin sincronización, porque "solo funciona a través de main". Más tarde, el código se adaptó para la multihilo, olvidando el estado mutable global, lo que causó errores muy difíciles de detectar.
Historia
En un programa embebido, se inicializó incorrectamente el CONFIG static a través de una función al inicio, pero no se garantizó que se llamara exactamente una vez. Como resultado, algunas partes del código accedieron a una configuración no inicializada (referencia nula).