今天和同事討論到fflush函數的作用, 本想php的文件系統函數應該是構建在系統的標准I/O庫之上的, 所以, 武斷的認為fflush的作用就是刷出標准I/O庫的緩沖, 相當於標准I/O庫的fflush函數....
後來跟蹤了一下代碼, 發現結果大相徑庭...
先說下結果吧:
1. php中的文件系統函數(fopen, fwrite, fread, fseek等)應用在普通文件上時, 內部使用的是open, write, read, seek等系統調用進行處理, 而沒有經過標准I/O庫.
2. fflush函數應用在普通文件上時, 不產生任何作用.
跟蹤過程:
從ext/standard/file.c中的
PHP_NAMED_FUNCTION(php_if_fopen)
作為入口, 最終找到main/streams/plain_wrapper.c中的如下定義
PHPAPI php_stream_ops php_stream_stdio_ops = {
php_stdiop_write, php_stdiop_read,
php_stdiop_close, php_stdiop_flush,
"STDIO",
php_stdiop_seek,
php_stdiop_cast,
php_stdiop_stat,
php_stdiop_set_option
};
這就是應用在普通文件上的主要的文件系統函數的底層實現
以php_stdiop_flush(對應php用戶態的fflush)為例:
static int php_stdiop_flush(php_stream *stream TSRMLS_DC)
{
php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract;
assert(data != NULL);
/*
* stdio buffers data in user land. By calling fflush(3), this
* data is send to the kernel using write(2). fsync'ing is
* something completely different.
*/
if (data->file) {
return fflush(data->file);
}
return 0;
}
而普通文件在初始化過程中(跟蹤open的過程中可以看到), 是沒有設置data->file這個字段的, 而是使用了data->fd....
因此這裡fflush不會被調用, 也就是說當fflush用在普通文件時, 無任何效果.
author: selfimpr mail: [email protected]