欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  php教程

[php内核]----文件系统函数用于普通文件时的一些情况

程序员文章站 2022-04-07 23:05:25
...
今天和同事讨论到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: lgg860911@yahoo.com.cn