write permisos open fputs español con php locking blocking atomic atomicity

php - permisos - ¿Debería LOCK_EX tanto en lectura como en escritura ser atómico?



php get line (2)

Como esta respuesta es larga, aquí está el resumen: No, file_get_contents() no es atómico, ya que no respeta los bloqueos de advertencia .

Acerca de los bloqueos de archivos en PHP:

En PHP, mientras se encuentra en una plataforma * nix, el bloqueo del sistema de archivos es solo un consejo. Por los documentos (énfasis mío):

PHP admite una forma portátil de bloquear archivos completos de forma consultiva (lo que significa que todos los programas de acceso deben usar la misma forma de bloqueo o no funcionará ). Por defecto, esta función se bloqueará hasta que se adquiera el bloqueo solicitado; esto se puede controlar (en plataformas que no sean de Windows) con la opción LOCK_NB documentada a continuación.

Por lo tanto, siempre que todos los procesos que acceden al archivo utilicen este método de bloqueo, está bien.

Sin embargo, si está escribiendo un archivo HTML estático con un servidor web sano, el bloqueo se ignorará. En el medio de la escritura, si llega una solicitud, Apache servirá el archivo parcialmente escrito. Los bloqueos no tendrán efecto en el otro proceso que lea el bloqueo.

La única excepción real es si usa la opción de montaje especial de -o mand en el sistema de archivos para habilitar el bloqueo obligatorio (pero eso no se usa mucho y puede tener una penalización de rendimiento).

Haga una lectura en el bloqueo de archivos para obtener más información. Es decir, la sección bajo Unix :

Esto significa que los procesos que cooperan pueden usar bloqueos para coordinar el acceso a un archivo entre ellos, pero los programas también son libres de ignorar los bloqueos y acceder al archivo de la forma que deseen.

Entonces, en conclusión, el uso de LOCK_EX creará un bloqueo de aviso en el archivo. Cualquier intento de leer el archivo solo se bloqueará si el lector respeta y / o verifica el bloqueo. Si no lo hacen, el bloqueo será ignorado (ya que puede ser).

Pruébalo. En un proceso:

file_put_contents(''test.txt'', ''Foo bar''); $f = fopen(''test.txt'', ''a+''); if (flock($f, LOCK_EX)) { sleep(10); fseek($f, 0); var_dump(fgets($f, 4048)); flock($f, LOCK_UN); } fclose($f);

Y mientras duerme, llama a esto:

$f = fopen(''test.txt'', ''a+''); fwrite($f, ''foobar''); fclose($f);

La salida será foobar ...

Sobre file_get_contents específicamente:

Para su otra pregunta específica, en primer lugar, no hay ningún parámetro LOCK_EX para file_get_contents . Así que no puedes pasar eso.

Ahora, mirando el código fuente , podemos ver la función file_get_contents definida en la línea 521. No hay llamadas a la función interna php_stream_lock como las hay cuando pasa file_put_contents(''file'', ''txt'', LOCK_EX); Definido en la línea 589 del mismo archivo.

Entonces, vamos a probarlo, vamos a:

En file1.php:

file_put_contents(''test.txt'', ''Foo bar''); $f = fopen(''test.txt'', ''a+''); if (flock($f, LOCK_EX)) { sleep(10); fseek($f, 0); var_dump(fgets($f, 4048)); flock($f, LOCK_UN); } fclose($f);

En file2.php:

var_dump(file_get_contents(''test.txt''));

Cuando se ejecuta, file2.php devuelve inmediatamente. Así que no, no parece que file_get_contents respete los bloqueos de archivos en absoluto ...

file_put_contents ( "file", "data", LOCK_EX )

para escribir (lo que significa - comprimir y escribir)

file_get_contents ( "file", LOCK_EX )

para leer (lo que significa - comprimir y luego leer)

¿Lanzará excepción? levantar un error? ¿Bloquear hasta que se adquiera el bloqueo? o al menos - ¿ debería ? ¿Hay alguna posibilidad de que PHP se comporte de esta manera algún día?

EDITAR: sé que es posible usar renombrar, me gustaría saber responder a esto ...


Las preguntas teóricas funcionan mucho mejor en Programmers que aquí.

En este punto, PHP no admite el bloqueo de archivos atómicos.

En pocas palabras, PHP no admite una operación combinada de fopen y flock , por lo que siempre habrá una pequeña ventana de oportunidad para que otro proceso bloquee un archivo que su proceso también abrió antes de que el proceso pueda bloquearlo.

Dicho esto, el flock se bloqueará, por defecto, hasta que se libere el bloqueo. Sin embargo, tenga en cuenta la nota de ircmaxell sobre los bloqueos de advertencia en Linux / BSD.

Nota: Para el proceso de lectura, es posible que desee convertirlo en un LOCK_SH lugar de LOCK_EX , de modo que varios subprocesos de lectores puedan bloquearlo al mismo tiempo. La escritura siempre debe hacerse utilizando LOCK_EX o la corrupción de datos de riesgo.

Nota 2: La nota anterior funciona porque solo puede adquirir bloqueos compartidos si no hay bloqueos exclusivos, pero un bloqueo exclusivo requiere que no haya ningún tipo de bloqueo antes de poder adquirir el bloqueo.