Articulo de referencia

Bloqueo de archivos

El bloqueo de archivos es un mecanismo que restringe el acceso a un archivo informático , o a una región de un archivo, permitiendo que solo un usuario o proceso lo modifique o ...

El bloqueo de archivos es un mecanismo que restringe el acceso a un archivo informático , o a una región de un archivo, permitiendo que solo un usuario o proceso lo modifique o elimine en un momento específico, e impidiendo la lectura del archivo mientras se está modificando o eliminando.

Los sistemas implementan mecanismos de bloqueo para evitar un escenario de actualización simultánea , que es un ejemplo de condición de carrera , al imponer la serialización de los procesos de actualización a cualquier archivo dado. El siguiente ejemplo ilustra el problema de la actualización simultánea:

  1. El proceso A lee el registro de un cliente de un archivo que contiene información de la cuenta, incluido el saldo de la cuenta del cliente y su número de teléfono.
  2. El proceso B ahora lee el mismo registro del mismo archivo, por lo que tiene su propia copia.
  3. El proceso A modifica el saldo de la cuenta en su copia del registro del cliente y vuelve a escribir el registro en el archivo.
  4. El proceso B, que aún conserva el valor obsoleto original del saldo de la cuenta en su copia del registro del cliente, actualiza el saldo de la cuenta y vuelve a escribir el registro del cliente en el archivo.
  5. El proceso B ha escrito en el archivo el valor obsoleto del saldo de la cuenta, lo que provoca la pérdida de los cambios realizados por el proceso A.

La mayoría de los sistemas operativos admiten el bloqueo de registros , lo que significa que se pueden bloquear registros individuales dentro de un archivo, aumentando así el número de procesos de actualización concurrentes . El mantenimiento de bases de datos utiliza el bloqueo de archivos, lo que permite serializar el acceso a todo el archivo físico subyacente. Si bien esto impide que otros procesos accedan al archivo, puede ser más eficiente que bloquear individualmente varias regiones del archivo, ya que elimina la sobrecarga de adquirir y liberar cada bloqueo.

El uso inadecuado de los bloqueos de archivos, al igual que cualquier otro bloqueo informático , puede provocar un rendimiento deficiente o bloqueos del sistema . El bloqueo de archivos también puede referirse a medidas de seguridad adicionales aplicadas por el usuario mediante la seguridad de Windows, los permisos NTFS o la instalación de un software de bloqueo de archivos de terceros.

En los ordenadores centrales

IBM fue pionera en el bloqueo de archivos en 1963 para su uso en computadoras centrales que utilizaban OS/360 , donde se denominó "control exclusivo". [ 1 ]

En Microsoft Windows

Microsoft Windows utiliza tres mecanismos distintos para gestionar el acceso a los archivos compartidos:

  1. utilizando controles de acceso compartido que permiten a las aplicaciones especificar el acceso compartido de archivos completos para lectura, escritura o eliminación [ 2 ]
  2. usar bloqueos de rango de bytes para arbitrar el acceso de lectura y escritura a regiones dentro de un solo archivo [ 3 ]
  3. Los sistemas de archivos de Windows impiden que los archivos ejecutables se abran para escritura o eliminación.

Windows hereda la semántica de los controles de acceso compartido del sistema MS-DOS , donde la función de compartir se introdujo en MS-DOS  3.3  . Por lo tanto, una aplicación debe permitir explícitamente el uso compartido al abrir un archivo; de lo contrario, tendrá acceso exclusivo de lectura, escritura y eliminación al archivo hasta que se cierre (se permiten otros tipos de acceso, como los necesarios para recuperar los atributos de un archivo).

Para un archivo abierto con acceso compartido, las aplicaciones pueden usar el bloqueo por rango de bytes para controlar el acceso a regiones específicas del archivo. Estos bloqueos especifican una región del archivo (desplazamiento y longitud) y el tipo de bloqueo (compartido o exclusivo). Cabe destacar que la región del archivo que se bloquea no tiene por qué contener datos, y las aplicaciones a veces aprovechan esta capacidad para implementar su funcionalidad.

Para las aplicaciones que utilizan las API de lectura/escritura de archivos en Windows, los sistemas de archivos que se ejecutan en Windows aplican bloqueos de rango de bytes (también conocidos como bloqueos obligatorios ). Para las aplicaciones que utilizan las API de asignación de archivos en Windows, no se aplican bloqueos de rango de bytes (también conocidos como bloqueos consultivos ). El bloqueo de rango de bytes también puede tener otros efectos secundarios en el sistema Windows. Por ejemplo, el mecanismo de uso compartido de archivos de Windows normalmente desactiva el almacenamiento en caché del lado del cliente de un archivo para todos los clientes cuando alguno de ellos utiliza bloqueos de rango de bytes . El cliente observará un acceso más lento porque las operaciones de lectura y escritura deben enviarse al servidor donde se almacena el archivo.

Un manejo inadecuado de errores en un programa puede provocar que un archivo quede bloqueado (ya sea mediante acceso compartido o bloqueo de archivos por rango de bytes) y que otras aplicaciones no puedan acceder a él. En tal caso, el usuario puede restablecer el acceso al archivo cerrando manualmente el programa defectuoso. Esto se suele hacer a través del Administrador de tareas .

El parámetro de modo de uso compartido (dwShareMode) de la función CreateFile[ 2 ] (utilizada para abrir archivos) determina cómo se comparte el archivo. Se puede especificar el modo de uso compartido para permitir el acceso de lectura, escritura o eliminación, o cualquier combinación de estos. Los intentos posteriores de abrir el archivo deben ser compatibles con todos los permisos de uso compartido otorgados previamente. Al cerrar el archivo, las restricciones de acceso se ajustan para eliminar las restricciones impuestas por esa apertura específica.

El tipo de bloqueo por rango de bytes se determina mediante el dwFlagsparámetro de la función LockFileEx[ 4 ] utilizada para bloquear una región de un archivo. También se puede utilizar la función de la API de Windows LockFile[ 5 ] , que adquiere un bloqueo exclusivo sobre la región del archivo.

Cualquier archivo que contenga un programa ejecutable que se esté ejecutando en el sistema informático (por ejemplo, un archivo .txt EXE, COM.txt DLLu CPLotro formato de archivo de programa binario ) normalmente está bloqueado por el propio sistema operativo, lo que impide que cualquier aplicación lo modifique o elimine. Cualquier intento de hacerlo será rechazado con un error de violación de uso compartido, a pesar de que el archivo del programa no esté abierto por ninguna aplicación. Sin embargo, se permite cierto acceso. Por ejemplo, un archivo de aplicación en ejecución puede ser renombrado o copiado (leído) incluso mientras se está ejecutando.

En Windows, las aplicaciones acceden a los archivos mediante identificadores de archivo . Estos identificadores se pueden explorar con la utilidad Explorador de procesos . Esta utilidad también permite cerrar los identificadores de forma forzada sin necesidad de finalizar la aplicación que los utiliza. Esto puede provocar un comportamiento inesperado , ya que el programa recibirá un error al usar el identificador cerrado forzosamente e incluso podría operar con un archivo inesperado, dado que el identificador podría reutilizarse.

Las ediciones Microsoft Windows XP y Server 2003 introdujeron la capacidad de instantáneas de volumen ( VSS) en NTFS , lo que permite que el software de copia de seguridad acceda a los archivos abiertos a pesar de cualquier bloqueo exclusivo. Sin embargo, a menos que el software se reescriba para admitir específicamente esta función, la instantánea solo será consistente en caso de fallo , mientras que las aplicaciones compatibles pueden ayudar al sistema operativo a crear instantáneas "transaccionalmente consistentes". Otros programas comerciales para acceder a archivos bloqueados en Windows incluyen File Access Manager y Open File Manager . Estos funcionan instalando sus propios controladores para acceder a los archivos en modo kernel .

En sistemas tipo Unix

Los sistemas operativos tipo Unix (incluidos Linux y macOS de Apple ) normalmente no bloquean automáticamente los archivos abiertos. Existen varios tipos de mecanismos de bloqueo de archivos en diferentes variantes de Unix, y muchos sistemas operativos admiten más de un tipo para garantizar la compatibilidad. El mecanismo más común es fcntl. Otros dos mecanismos son flock(2)y lockf(3), cada uno de los cuales puede implementarse sobre fcntlo por separado de fcntl. Aunque algunos tipos de bloqueos pueden configurarse como obligatorios, los bloqueos de archivos en Unix son por defecto consultivos . Esto significa que los procesos cooperativos pueden usar bloqueos para coordinar el acceso a un archivo entre ellos, pero los procesos no cooperativos también pueden ignorar los bloqueos y acceder al archivo como deseen. En otras palabras, los bloqueos de archivos solo bloquean a otros bloqueadores de archivos, no a la E/S.

Se ofrecen dos tipos de bloqueos: bloqueos compartidos y bloqueos exclusivos. En el caso de fcntl, se pueden aplicar diferentes tipos de bloqueos a diferentes secciones (rangos de bytes) de un archivo, o bien al archivo completo. Los bloqueos compartidos pueden ser mantenidos por varios procesos al mismo tiempo, pero un bloqueo exclusivo solo puede ser mantenido por un proceso y no puede coexistir con un bloqueo compartido. Para adquirir un bloqueo compartido, un proceso debe esperar hasta que ningún proceso mantenga ningún bloqueo exclusivo. Para adquirir un bloqueo exclusivo, un proceso debe esperar hasta que ningún proceso mantenga ninguno de los dos tipos de bloqueo. A diferencia de los bloqueos creados por fcntl, los creados por flockse conservan entre fork, lo que los hace útiles en servidores de bifurcación. Por lo tanto, es posible que más de un proceso mantenga un bloqueo exclusivo en el mismo archivo, siempre que estos procesos compartan una relación filial y el bloqueo exclusivo se haya creado inicialmente en un solo proceso antes de ser duplicado en un fork.

Los bloqueos compartidos a veces se denominan "bloqueos de lectura" y los bloqueos exclusivos, "bloqueos de escritura". Sin embargo, dado que los bloqueos en Unix son consultivos, esta distinción no se aplica. Por lo tanto, es posible que una base de datos tenga el concepto de "escrituras compartidas" frente a "escrituras exclusivas"; por ejemplo, modificar un campo directamente puede estar permitido con acceso compartido, mientras que la recolección de basura y la reescritura de la base de datos pueden requerir acceso exclusivo.

Los bloqueos de archivos se aplican al archivo en sí, no a su nombre. Esto es importante, ya que Unix permite que varios nombres hagan referencia al mismo archivo. Junto con el bloqueo no obligatorio, esto proporciona una gran flexibilidad para acceder a los archivos desde múltiples procesos. Por otro lado, el enfoque de bloqueo cooperativo puede generar problemas cuando un proceso escribe en un archivo sin respetar los bloqueos establecidos por otros procesos.

Por esta razón, algunos sistemas operativos tipo Unix también ofrecen soporte limitado para el bloqueo obligatorio . [ 6 ] En tales sistemas, un archivo cuyo setgidbit está activado pero cuyo bit de ejecución de grupo está desactivado cuando se abre ese archivo estará sujeto a bloqueo obligatorio automático si el sistema de archivos subyacente lo admite. Sin embargo, las particiones NFS no locales tienden a ignorar este bit. [ 7 ] Si un archivo está sujeto a bloqueo obligatorio, los intentos de leer de una región que está bloqueada con un bloqueo exclusivo, o de escribir en una región que está bloqueada con un bloqueo compartido o exclusivo, se bloquearán hasta que se libere el bloqueo. Esta estrategia se originó por primera vez en System  V y se puede ver hoy en los sistemas operativos Solaris , HP-UX y Linux. Sin embargo, no forma parte de POSIX, y los sistemas operativos derivados de BSD como FreeBSD , OpenBSD , NetBSD y macOS de Apple no la admiten. [ 8 ] Linux también admite el bloqueo obligatorio-o mand a través del parámetro especial para el montaje del sistema de archivos ( mount(8)), pero esto rara vez se usa.

Algunos sistemas operativos tipo Unix impiden los intentos de abrir el archivo ejecutable de un programa en ejecución para escritura; esta es una tercera forma de bloqueo, distinta de las proporcionadas por fcntly flock.

Problemas

Más de un proceso puede mantener un bloqueo exclusivo flocksobre un archivo determinado si dicho bloqueo se duplicó en un proceso posterior fork. Esto simplifica la programación para servidores de red y ayuda a prevenir condiciones de carrera, pero puede resultar confuso para quienes no estén familiarizados con el tema.

Los bloqueos obligatorios no tienen efecto en unlink. En consecuencia, ciertos programas pueden, de hecho, eludir el bloqueo obligatorio. Stevens y Rago (2005) observaron que el ededitor efectivamente lo hizo. [ 9 ]

El flockfuncionamiento de los bloqueos en sistemas de archivos de red, como NFS , depende de la implementación. En sistemas BSDflock , las llamadas a un descriptor de archivo abierto a un archivo en una partición montada en NFS no tienen efecto . En Linux anterior a la versión 2.6.12, flocklas llamadas a archivos NFS solo actuaban localmente. El kernel  2.6.12 y versiones posteriores implementan flocklas llamadas a archivos NFS mediante bloqueos de rango de bytes POSIX. Estos bloqueos serán visibles para otros clientes NFS que implementen bloqueos POSIXfcntl de estilo , pero invisibles para aquellos que no lo hagan. [ 10 ]

Las actualizaciones y degradaciones de bloqueo liberan el bloqueo anterior antes de aplicar el nuevo. Si una aplicación degrada un bloqueo exclusivo a uno compartido mientras otra aplicación está bloqueada esperando un bloqueo exclusivo, esta última podría obtenerlo y bloquear a la primera. Esto significa que las degradaciones de bloqueo pueden provocar bloqueos, lo cual puede resultar contraintuitivo.

Todosfcntl los bloqueos asociados a un archivo para un proceso determinado se eliminan cuando dicho proceso cierra cualquierfcntl descriptor de archivo para ese archivo, incluso si nunca se solicitó un bloqueo para ese descriptor de archivo. Además, los bloqueos no se heredan a un proceso hijo. La fcntlsemántica de cierre resulta particularmente problemática para las aplicaciones que llaman a bibliotecas de subrutinas que pueden acceder a archivos. Ninguno de estos "errores" se produce al usar flockbloqueos de estilo real.

La conservación del estado de bloqueo en los descriptores de archivos abiertos que se pasan a otro proceso mediante un socket de dominio Unix depende de la implementación.

Problemas de E/S con búfer

Una fuente de fallo de bloqueo se produce cuando la E/S con búfer tiene búferes asignados en el espacio de trabajo local del usuario, en lugar de en un grupo de búferes del sistema operativo. fready fwritese utilizan comúnmente para realizar E/S con búfer, y una vez que se lee una sección de un archivo, otro intento de leer esa misma sección, muy probablemente, obtendrá los datos del búfer local. El problema es que otro usuario conectado al mismo archivo tiene sus propios búferes locales, y le está sucediendo lo mismo. Un defwrite datos obtenidos del búfer por freadno obtendrá los datos del archivo en sí, y algún otro usuario podría haberlo modificado. Ambos podrían usar para garantizar el acceso exclusivo, lo que evita escrituras simultáneas, pero dado que las lecturas leen del búfer y no del archivo en sí, cualquier dato modificado por el usuario n.° 1 puede ser perdido por el usuario n.° 2 (sobrescrito). La mejor solución a este problema es usar E/S sin búfer ( y ) con , lo que también significa usar en lugar de y . Por supuesto, tendrá que hacer ajustes para los parámetros de la función y los resultados devueltos. En términos generales, la E/S con búfer no es segura cuando se utiliza con archivos compartidos.flock  readwriteflocklseekfseekftell

En AmigaOS

En AmigaOS , se puede adquirir un bloqueo sobre un archivo (o directorio) mediante la Lockfunción (en el dos.library). Un bloqueo puede ser compartido (otros procesos pueden leer el archivo/directorio, pero no modificarlo ni eliminarlo) o exclusivo, de modo que solo el proceso que adquiere el bloqueo con éxito puede acceder al objeto o modificarlo. El bloqueo se aplica a todo el objeto, no a una parte de él. El bloqueo debe liberarse con la UnLockfunción: a diferencia de Unix, el sistema operativo no desbloquea implícitamente el objeto cuando finaliza el proceso.

Archivos de bloqueo

Los scripts de shell y otros programas suelen emplear una estrategia similar al bloqueo de archivos: la creación de archivos de bloqueo . Estos archivos, cuyo contenido es irrelevante (aunque a menudo se encuentra el identificador del proceso que posee el bloqueo), tienen como único propósito indicar que algún recurso está bloqueado. Un archivo de bloqueo suele ser la mejor opción si el recurso a controlar no es un archivo regular, por lo que no se aplican los métodos de bloqueo de archivos. Por ejemplo, un archivo de bloqueo podría controlar el acceso a un conjunto de recursos relacionados, como varios archivos, directorios, un grupo de particiones de disco o el acceso selectivo a protocolos de nivel superior, como servidores o conexiones a bases de datos.

Al utilizar archivos de bloqueo, es fundamental asegurarse de que las operaciones sean atómicas . Para obtener un bloqueo, el proceso debe verificar que el archivo de bloqueo no existe y luego crearlo, impidiendo que otro proceso lo cree mientras tanto. Existen varios métodos para lograr esto, entre ellos:

  • Utilizando el lockfilecomando (un creador de archivos de semáforo condicional distribuido en el procmailpaquete).
  • API que crean un archivo, pero fallan si el archivo ya existe. (Estas API están disponibles en lenguajes como C o C++, y los scripts de shell pueden usar noclobber ).
  • Utilizando el mkdircomando y comprobando el código de salida para detectar fallos [ 11 ]

Los archivos de bloqueo suelen nombrarse con una tilde ( ~) como prefijo del nombre del archivo que bloquean, o con una copia del nombre completo del archivo con el sufijo .LCK . Si bloquean un recurso distinto a un archivo, pueden nombrarse de forma más arbitraria.

Software de desbloqueo

Un desbloqueador es una utilidad que se usa para determinar qué proceso está bloqueando un archivo y muestra una lista de procesos, así como opciones sobre qué hacer con el proceso (terminar tarea, desbloquear, etc.), junto con una lista de opciones de archivo como eliminar o renombrar. Su propósito es eliminar bloqueos de archivos incorrectos o obsoletos, que a menudo surgen de situaciones anómalas, como procesos bloqueados o quebrados, que provocan bloqueos de archivos que persisten a pesar de que el proceso propietario ya haya terminado. En algunos sistemas tipo Unix, se pueden usar utilidades como fstaty lockfpara inspeccionar el estado de los bloqueos de archivos por proceso, por nombre de archivo o ambos.

En los sistemas Windows, si un archivo está bloqueado, es posible programar su traslado o eliminación para que se realice en el siguiente reinicio. Este método lo suelen usar los instaladores para reemplazar archivos del sistema bloqueados.

Sistemas de control de versiones

En los sistemas de control de versiones, el bloqueo de archivos se utiliza para evitar que dos usuarios modifiquen la misma versión de un archivo simultáneamente y, al guardar, el segundo usuario sobrescriba los cambios del primero. Esto se implementa marcando los archivos bloqueados como de solo lectura en el sistema de archivos. Un usuario que desea modificar el archivo realiza una operación de desbloqueo (también llamada extracción), y hasta que se realice una operación de registro (almacenamiento) o se revierta el bloqueo, nadie más puede desbloquear el archivo.

Programación

Rust admite el bloqueo de archivos mediante los métodos lock, try_lock, lock_shared, try_lock_sharedy . [ 12 ]unlock

usar std :: fs :: File ;fn main () -> std :: io :: Result < () > { let f = File :: create ( "foo.txt" ) ? ; f . lock () ? ; Ok (()) }

.NET admite el bloqueo de archivos mediante un FileStream. [ 13 ]

usando System.IO ;var textLength = 1 ; var byteCount = 1 ;usando var stream = new FileStream ( "foo.txt" , FileMode . OpenOrCreate ); stream . Lock ( textLength - 1 , byteCount );

PHP admite el bloqueo de archivos mediante la flockfunción. [ 14 ]

$fp = fopen ( "/tmp/lock.txt" , "r+" );if ( flock ( $fp , LOCK_EX )) { // Adquiere un bloqueo exclusivo ftruncate ( $fp , 0 ); // Trunca el archivo fwrite ( $fp , "Escribe algo aquí \n " ); fflush ( $fp ); // Vacía la salida antes de liberar el bloqueo flock ( $fp , LOCK_UN ); // Libera el bloqueo } else { echo "¡No se pudo obtener el bloqueo!" ; }fclose ( $fp );

Véase también

Referencias

  1. Sistema operativo IBM System/360: Referencia del lenguaje de control de trabajos (PDF) . IBM . Junio ​​de 1971. págs. 162–164 . GC28-6704-1. 
  2. 1 2 " función" . Kit de desarrollo de software de Windows. Microsoft Docs . windows-sdk-content. Microsoft Corporation . Consultado el 7 de noviembre de 2018 .CreateFileW
  3. " función" . Kit de desarrollo de software de Windows. Microsoft Docs . windows-sdk-content. Microsoft Corporation . Consultado el 7 de noviembre de 2018 .LockFileEx
  4. " función" . Kit de desarrollo de software de Windows. Microsoft Docs . windows-sdk-content. Microsoft Corporation . Consultado el 5 de julio de 2020 .LockFileEx
  5. " función" . Kit de desarrollo de software de Windows. Microsoft Docs . windows-sdk-content. Microsoft Corporation . Consultado el 5 de julio de 2020 .LockFile
  6. "Bloqueo obligatorio de archivos para el sistema operativo Linux" . kernel.org . Documentación / Sistemas de archivos . Consultado el 8 de octubre de 2011 .
  7. "Use , , y Sticky Bits with Server for NFS" . cc731734(WS.10) . Recuperado el 8 de octubre de 2011 .SetuidSetgid
  8. Viega, John; Messier, Matt (2003). "2.8 Bloqueo de archivos". Secure Programming Cookbook for C and C++ (1.ª ed.). Sabastopol, CA: O'Reilly Media. p. 792. ISBN   978-0-596-00394-4La compatibilidad con bloqueos obligatorios varía considerablemente entre las distintas variantes de Unix. Tanto Linux como Solaris admiten bloqueos obligatorios, pero Darwin , FreeBSD , NetBSD y OpenBSD no, a pesar de exportar la interfaz que utilizan Linux y Solaris para ello. En estos sistemas , dicha interfaz crea bloqueos consultivos. La compatibilidad con bloqueos obligatorios no se extiende a NFS.
  9. Stevens, W. Richard; Rago, Stephen A. (27 de junio de 2005). Programación avanzada en el entorno UNIX (Segunda edición). Addison-Wesley Professional. pág. 456. ISBN   978-0201433074.
  10. "Mensajes de error comunes" . nfs.sourceforge.net . Preguntas frecuentes sobre NFS en Linux: D. Source Forge.
  11. "Bloquea tu script (para evitar la ejecución en paralelo)" . Archivado del original el 1 de agosto de 2010.
  12. "Archivo en std::fs - Rust" . doc.rust-lang.org . Consultado el 26 de octubre de 2025 .
  13. "Método FileStream.Lock(Int64, Int64) (System.IO)" . learn.microsoft.com . Consultado el 26 de octubre de 2025 .
  14. "PHP: flock - Manual" . www.php.net . Consultado el 26 de octubre de 2025 .
  • Todo lo que nunca quisiste saber sobre el bloqueo de archivos : una revisión de las opciones de bloqueo de archivos de Unix y sus problemas (13 de diciembre de 2010).
  • Bloqueos POSIX privados de archivos , un artículo de LWN.net sobre bloqueos de archivos compatibles con Linux que se comportan de manera diferente a los bloqueos POSIX en cuanto a herencia y comportamiento al cerrarse.