【问题标题】:stream_set_write_buffer or file locking in PHP?PHP 中的 stream_set_write_buffer 或文件锁定?
【发布时间】:2015-07-29 21:01:46
【问题描述】:

我正在尝试创建一个缓存系统,可以尽可能快地写入大量数据(8 KB 到 200 KB 之间)。

目前我正在使用类似于下面的代码应用文件锁定功能:

$file_handle=fopen($file_name,"w");
flock($file_handle,LOCK_EX);
fwrite($file_handle,$all_data);
flock($file_handle,LOCK_UN);
fclose($file_handle);

如果许多进程同时运行相同的脚本,这是一次只允许一个进程写入文件的最佳速度方式,还是应该包括stream_set_write_buffer($file_handle,0);,或者我应该放弃文件锁定?

【问题讨论】:

    标签: php performance file stream locking


    【解决方案1】:

    简而言之:

    file_put_contents($file_name, $all_data, LOCK_EX);
    

    长篇大论: 您的代码存在一个问题:“w”模式在获取锁之前截断文件。如果两个单独的进程截断了一个文件,一个写入 200Kb,另一个写入 8Kb,则文件中将留下 192Kb 的垃圾。我建议在写入所有数据后以“c”模式打开文件并在最后截断它:

    $file_handle = fopen($file_name, 'c');
    stream_set_write_buffer($file_handle, 0); // try to disable write buffering
    flock($file_handle, LOCK_EX);
    fwrite($file_handle, $all_data); // write to possibly pre-allocated space
    ftruncate($file_handle, strlen($all_data)); // remove gabage left from previous write
    fflush($file_handle); // flush write buffers if enabled
    flock($file_handle, LOCK_UN);
    fclose($file_handle);
    

    'c' 打开文件仅用于写入。如果文件不存在,则创建它。如果它存在,它既不会被截断(与“w”相反),对该函数的调用也不会失败(就像“x”一样)。文件指针位于文件的开头。如果希望在尝试修改文件之前获得建议锁(请参阅flock()),这可能很有用,因为使用'w'可以在获得锁之前截断文件(如果需要截断,可以使用 ftruncate()在请求锁定后使用)。

    您需要通过调用fflush() 或禁用写缓冲来确保在释放锁之前刷新写缓冲区。由于stream_set_write_buffer(); 可能会失败,因此最好还是拥有fflush()。另请注意,写入缓冲旨在提高顺序写入的性能。由于您只执行一次写入操作,写入缓冲区会稍微降低性能,因此最好先尝试禁用它。

    【讨论】:

      猜你喜欢
      • 2011-07-23
      • 2015-04-14
      • 1970-01-01
      • 2020-05-19
      • 2014-09-04
      • 1970-01-01
      • 2015-01-26
      • 1970-01-01
      • 2011-08-24
      相关资源
      最近更新 更多