2012-08-05 16 views
7

veo a la gente usando rebaño como esta:php rebaño y fread y fwrite

if (!$fp = fopen($file_name, 'wb')) 
{ 
    return FALSE; 
} 

if (flock($fp, LOCK_EX)) 
{ 
    fwrite($fp, serialize($data)); 
    flock($fp, LOCK_UN); 
} 

también esto:

if (!$fp = @fopen($file_name, 'rb')) 
{ 
    return FALSE; 
} 

flock($fp, LOCK_SH); 

$data = ''; 

if (filesize($file_name) > 0) 
{ 
    $data = unserialize(fread($fp, filesize($file_name))); 
} 

¿Pero no hay una posibilidad de que alguien más va a editar el archivo entre el fopen llamada y la llamada flock? y la misma pregunta para fread


EDIT:
para aclarar por qué estoy haciendo esta ... Estoy basando mi pregunta sobre el código here, En una situación de almacenamiento en caché de MySQL, lo que está a tope 20 personas de todos pueden acceder al archivo al mismo tiempo si todos pueden entrar entre el fopen y el rebaño?

¿Es ese código infalible?

Respuesta

6

Usted pregunta:

no hay una posibilidad de que alguien else editará el archivo entre la llamada fopen y la llamada en bandada? y la misma pregunta para fread

Sí, no, quizás. Respuesta corta: asuma "sí" y actúe con cuidado.

Sí, en ese bloqueo tradicional basado en flock() es meramente advisory, por lo que otros procesos (o incluso el mismo proceso) son libres de ignorar los bloqueos. En la práctica, esto no es un problema, ya que flock() es utilizado por un código de cliente de buen comportamiento: no lee hasta que obtiene un LOCK_SH, y no escribe a menos que haya obtenido un LOCK_EX - en aplicación- archivos específicos

No, en la ejecución de ese rebaño de PHP() puede ser obligatoria en ciertos sistemas operativos, por el documentation, que también podría requerir el apoyo del sistema de archivos (por ejemplo, al igual que con la opción mand bajo Linux). Entonces, otros procesos no podrían ignorar esos bloqueos.

Quizás, porque el subsistema de secuencias en PHP 5 implementa algo de locking bookkeeping más allá de lo que proporciona el sistema operativo. Esto puede, por ejemplo, evitar que el mismo proceso (pero no otro) haga caso omiso de sus propios bloqueos de asesoramiento. El comportamiento might surprise algunos. Aun así, este tipo de bloqueo no sería obligatorio entre procesos no relacionados.

Para la portabilidad, solo asuma la semántica más débil (el "sí" de arriba) y restrinja la bandada() ing al código de buen comportamiento en los archivos de bloqueo específicos de la aplicación elegidos de antemano.

+0

En caso de que el caché sea utilizado solo por ese script en particular, no pasará nada. Si alguien va a golpear el archivo de, digamos, shell - seguro, sucederán cosas malas. – favoretti

+0

Sí, pero no es el caso que LOCK_EX, por ejemplo, fuerce de alguna manera 'fread' a" no devolver nada ", como decía otro comentario. – pilcrow

+0

Si lee los comentarios en el sitio de PHP a flock(), realmente lo hace, a pesar de que el bloqueo es de advertencia. Dicho esto, el bloqueo obligatorio, por ejemplo, de Linux solo se puede lograr mientras se trabaja con sistemas de archivos que explícitamente lo soportan y se montan como tales. – favoretti

2

El primer fragmento es infalible, si no puede obtener un bloqueo en el archivo, no escriba. Si alguien más editó el archivo entre fopen() y flock(), su identificador de archivo apuntará a la última versión, ya que fopen() se une a una secuencia, en lugar de a una "instantánea".

No se garantiza que el segundo ejemplo funcione, porque el valor de retorno de flock() no está marcado, por lo que si no ha adquirido el bloqueo, el código subsiguiente se ejecutará de todos modos.

[editar] Declaración eliminado esa cerradura lector no importa, lo que realmente hace, como se explica en los comentarios a continuación :)

+0

Estoy basando mi pregunta en el código [** aquí, **] (http://www.jongales.com/blog/2009/02/18/simple-file-based-php-cache-class /) En una situación de almacenamiento en caché de mysql, ¿qué impide que 20 personas de todo el mundo puedan acceder al archivo al mismo tiempo en ese caso según el código de esa clase? – qwertymk

+0

Para leer, nada, que es lo más probable, lo que quiere, acceso simultáneo a la lectura de caché, en lugar de uno exclusivo. Para escribir, exactamente ese bloqueo adquirido evitará que otras personas escriban en el caché. ¿Qué es exactamente lo que te molesta con ese código? – favoretti

+0

Supongo que un problema menor, que si 100.000 personas intentan establecer el mismo archivo de caché y 20,000 reciben llamadas entre el fopen y el rebaño, habrá 19.999 escrituras innecesarias, también algunas de esas personas habrán hecho un control para ver si el el caché está actualizado y habrá perdido el nuevo tiempo de archivo que se obtiene. ¿Es eso incluso un problema? – qwertymk

Cuestiones relacionadas