使用读写缓冲
来源:互联网 发布:mac梦幻西游文件夹 编辑:程序博客网 时间:2024/05/18 20:50
进程缓冲区
我们慢慢来说明为什么要使用缓冲:
- 只有工作在管理员模式下,即只有内核代码才可以访问磁盘、终端、打印机等设备,还可以访问全部的内存。而用户模式下只访问特定区域的内存空间。
- 系统调用就是要从用户空间陷入内核空间,进入管理员模式。系统调用是很花时间的,原因:(1)执行权从用户代码转移到内核代码本身要进行数据传输;(2)管理员模式对应特殊的堆栈和内存环境,系统调用前必须建立好,系统调用后又要把堆栈和内存环境恢复成用户程序运行时的状态,这种切换需要消耗很多时间。
- read()和write()要访问磁盘,它们是系统调用,为节约时间应尽量减少read()和write()的调用次数,为达到此目的就要增大文件缓冲。
下面的代码是自己实现使用缓冲区的who命令实现。
#include<stdio.h>#include<utmp.h>#include<string.h>#include<stdlib.h>#include<time.h>#include<sys/types.h>#include<fcntl.h>#define BUFSIZE 16 //缓冲区中存放16条记录#define NULLUT ((struct utmp*)NULL) //定义一个空指针,不指向任何实际的对象或函数#define UTSIZE (sizeof(struct utmp))#define SHOWHOSTint my_utmp_open(char *filename);struct utmp* my_utmp_next();int my_utmp_reload();void my_utmp_close();void show_info(struct utmp*);static char utmpbuf[BUFSIZE*UTSIZE]; //缓冲区大小static int num_recs; //缓冲区中的数据个数static int cur_rec; //缓冲区中已经使用的数据个数static int fd_utmp=-1; //utmp文件的描述符int my_utmp_open(char *filename){ fd_utmp=open(filename,O_RDONLY); cur_rec=num_recs=0; return fd_utmp;}struct utmp* my_utmp_next(){ struct utmp *result; if(fd_utmp==-1) //文件打开失败 return NULLUT; if(cur_rec==num_recs && my_utmp_reload()==0) //缓冲区已读完,就从文件向缓冲区reload新内容。如果从文件中已读不出更多的内容,则返回空指针 return NULLUT; result=(struct utmp*)&utmpbuf[cur_rec*UTSIZE]; cur_rec++; return result;}int my_utmp_reload(){ int num=read(fd_utmp,utmpbuf,BUFSIZE*UTSIZE); //最多读取16条记录 num_recs=num/UTSIZE; //实际读取的记录数 cur_rec=0; return num_recs;}void my_utmp_close(){ if(fd_utmp!=-1) close(fd_utmp);}int main(){ struct utmp *record; if(my_utmp_open("/var/run/utmp")==-1){ //打开文件 perror("fopen"); exit(0); } while((record=my_utmp_next())!=NULLUT){ //循环读取记录(结构体) show_info(record); } my_utmp_close(); //关闭文件 return 0;}void show_info(struct utmp *buf){if(buf->ut_type!=USER_PROCESS)return; printf("%-8s ",buf->ut_name); //输出用户名 printf("%-12s ",buf->ut_line); //终端设备名 time_t timelong=buf->ut_time; struct tm *localnow=localtime(&timelong); printf("%d-%d-%d %d:%d ",localnow->tm_year+1990,localnow->tm_mon+1,localnow->tm_mday,localnow->tm_hour,localnow->tm_min); //登录时间#ifdef SHOWHOST printf("(%s)",buf->ut_host);#endif printf("\n");}
内核缓冲区
管理员模式和用户模式之间切换需要时间,相比之下,磁盘I/O消耗的时间更多,因此内核也利用缓冲技术来提高对磁盘的访问速度。
因此read函数并不是把数据直接从磁盘读到进程缓冲区,而是从内核缓冲区读到进程缓冲区;同样write也不会都导致内核的写磁盘操作,只有当内核缓冲区积累到一定量时才一次写入磁盘,有时突然断电,则内核缓冲区的数据会丢失。
当进程要求的数据块不在内核缓冲区时,内核把相应的数据加到请求数据列表中,然后挂起该进程,为其他进程服务。一段时间后(很短),内核把相应数据从磁盘读到内核缓冲区,然后再把数据复制到进程缓冲区,最后唤起被挂起的进程。
- 使用读写缓冲
- 读写锁ReadWriteLock的基本使用,创建一个缓冲池。
- JAVA IO :使用带缓冲的字节流读写数据
- 使用带有缓冲的字节流读写数据
- 使用带有缓冲的字符流读写数据
- java 使用带有缓冲的字符流读写数据
- 使用缓冲字节流:BufferedInputStream与BufferedOutputStream读写数据
- 一个读写缓冲模块
- 关于流的缓冲读写
- java IO流之三 使用缓冲流来读写文件
- 一个非常简单的缓冲—使用Java5提供的读写锁处理多线程操作
- IO中使用缓冲读写操作控制台数据的newLine()方法
- java18.IO操作------使用带缓冲的字节流读写数据
- java20.IO操作------使用带有缓冲的字符流读写数据
- java-IO操作——使用带有缓冲的字符流读写数据
- java IO流之三 使用缓冲流来读写文件
- java IO流之三 使用缓冲流来读写文件
- 使用缓冲功能的BufferedReader和BufferedWriter复制文本文件,按照行读写
- deque的实现
- 红黑树
- perl写入文件时中文乱码终极解决方案
- 编写who命令--从Linux中学习Linux
- 自己编写more命令
- 使用读写缓冲
- 实现ll命令
- UNIX时钟
- 信号通信
- execvp
- 环境
- I/O重定向和管道
- fdopen和popen
- 进程间协作、同步