Current Location: Home> Latest Articles> How to Ensure File Operation Atomicity and Safety by Using fsync and flock Together

How to Ensure File Operation Atomicity and Safety by Using fsync and flock Together

M66 2025-06-26

When performing file operations in PHP, ensuring atomicity and safety is crucial, especially in multi-process or multi-thread environments. The flock() function and fsync() function are two commonly used tools that, when combined, can effectively guarantee file operation integrity, avoiding issues such as race conditions and data loss. This article will introduce these two functions and explain how to use them together properly.

1. flock() Function: Implementing File Locks

The flock() function is used to lock a file to prevent multiple processes from modifying the same file at the same time, which could result in data corruption. It provides two types of locks: shared locks (LOCK_SH) and exclusive locks (LOCK_EX).

  • Shared lock (LOCK_SH): Allows multiple processes to read the file, but does not allow writing.

  • Exclusive lock (LOCK_EX): Exclusive lock, allowing one process to write to the file while other processes cannot read or write.

Example code:

<?php
$fp = fopen('data.txt', 'c+');
if (flock($fp, LOCK_EX)) { // Acquire exclusive lock
    // Perform file write operation
    fwrite($fp, "Writing data\n");
    fflush($fp); // Write buffered data to the file system
    flock($fp, LOCK_UN); // Release lock
}
fclose($fp);
?>

2. fsync() Function: Forcing Data to Disk

PHP does not directly provide the fsync() function, but you can use the fflush() function to flush the buffer. The fsync() system call ensures that the operating system writes the kernel's cached data to disk. Although fflush() will flush the buffer, it does not guarantee the persistence of data on the disk. In Linux environments, stream_get_meta_data and fstat can be used with posix_fsync (which requires extension support) to achieve this.

Example call (in supported environments):

<?php
$fp = fopen('data.txt', 'c+');
if (flock($fp, LOCK_EX)) {
    fwrite($fp, "Writing data\n");
    fflush($fp);
    // posix_fsync ensures data is written to disk
    if (function_exists('posix_fsync')) {
        posix_fsync($fp);
    }
    flock($fp, LOCK_UN);
}
fclose($fp);
?>

3. Combining flock() and fsync() to Ensure File Operation Atomicity and Safety

  • Atomicity: The flock() function ensures that only one process can write to the file at a time, preventing race conditions.

  • Safety: Using fflush() and fsync() (or similar functionality) ensures that data is written to the disk, preventing data loss due to system crashes or power failures.

Full example:

<?php
$file = '/path/to/data.txt';
$fp = fopen($file, 'c+');
if (!$fp) {
    die('Unable to open file');
}
<p>if (flock($fp, LOCK_EX)) {<br>
// Move the file pointer to the end to avoid overwriting<br>
fseek($fp, 0, SEEK_END);<br>
fwrite($fp, "Writing data safely\n");<br>
fflush($fp); // Write PHP buffer data to the OS cache</p>
if (function_exists('posix_fsync')) {
    posix_fsync($fp);
}

flock($fp, LOCK_UN);

} else {
echo "Unable to acquire file lock";
}

fclose($fp);
?>

4. Conclusion

  • The flock() function ensures atomicity of concurrent file operations by preventing data corruption when writing concurrently.

  • The fflush() and fsync() functions ensure that data is written from the program's buffer to the OS cache and then synchronized to the disk, enhancing data safety.

  • Combining these two functions significantly reduces the risk during the file write process, making it suitable for use cases such as log writing and configuration file updates where secure writes are needed.

If you need to ensure the stability and safety of file operations in your development, it is recommended to combine the principles of flock() and fsync().


fclose($fp);
?>