1.内核缓冲
内核操作磁盘时,内核会将磁盘上的数据块复制到内核缓冲区,当一个用户空间中的进程要从磁盘中读取数据时,内核一般不直接读取磁盘,而是将内核缓冲区中的数据复制到进程缓冲区。当进程要求的数据快不再内核缓冲区时,内核会把相应的数据快加入到请求数据列表中,然后把该进程挂起,接着为其他进程服务。一段时间后(很短),内核会把相应的数据块读到内核缓冲区,然后复制到进程缓冲区,最后被挂起的进程被唤醒。
2.模仿内核缓冲作用(将utmp中数据读到buffer中)非完整程序,程序片段
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <utmp.h>
#define NRECS 16
#define NULLUT ((struct utmp *)NULL)
#define UTSIZE (sizeof(struct utmp))
static char utmpbuf[NRECS * UTSIZE]; /* storage */
static int num_recs; /* num stored */ //每次读入的数据个数
static int cur_rec; /* next to go */ //缓冲区中当前的已读的数据个数
static int fd_utmp = -1; /* read from */
utmp_open( char *filename )
{
fd_utmp = open( filename, O_RDONLY ); /* open it */
cur_rec = num_recs = 0; /* no recs yet */ //初始化
return fd_utmp; /* report */
}
struct utmp *utmp_next()
{
struct utmp *recp;
if ( fd_utmp == -1 ) /* error ? */
return NULLUT;
if ( cur_rec==num_recs && utmp_reload()==0 ) /* any more ? */ //缓冲区中已读取数据等于缓冲区个数且不能从内核获得数据,即内核数据已经全部取完
return NULLUT;
/* get address of next record */
recp = ( struct utmp *) &utmpbuf[cur_rec * UTSIZE]; //返回下一个缓冲区的数据
cur_rec++;
return recp;
}
int utmp_reload()
/*
* read next bunch of records into buffer
*/
{
int amt_read;
/* read them in */
amt_read = read( fd_utmp , utmpbuf, NRECS * UTSIZE ); //读入缓冲区的数据个数*UTSIZE
/* how many did we get? */
num_recs = amt_read/UTSIZE; //读到缓冲区的数据个数
/* reset pointer */
cur_rec = 0;
return num_recs;
}
utmp_close()
{
if ( fd_utmp != -1 ) /* don't close if not */
close( fd_utmp ); /* open */
}