ch12学习笔记(I/O)
知识点归纳
I/O缓冲区:内核中的一系列NBUF缓冲区用作缓冲区缓存。每个缓冲区用一个结构体表示。
typdef struct buf{
struct buf *next_free; //freelist pointer
struct buf *next_dev; //dev_list pointer
int dev,blk; //assigned disk block;
int opcode; //READ|WRITE
int dirty; //buffer data modified
int async; //ASYNC write flag
int valid; //buffer data valid
int busy; //buffer is in use
int wanted; //some process needs this buffer
struct, semaphore lock=l ; //buffer locking semaphore; value=L
struct semaphore iodone=0; //for process to wait for I/O completion;
char buf[BLKSIZE]; //block data area
} BUFFER;
BUFFER buf[NBUF], *freelist; // NBUF buffers and free buffer list
设备表:每个块设备用一个设备表结构表示。
struct devtab{
u16 dev; // major device number
BUFFER *dev_list; // device buffer list
BUFFER*io_queue // device I/0 queue
}devtab[NDEV];
缓冲区初始化:当系统启动时,所有I/O缓冲区都在空闲列表中,所有设备列表和T/O队列均为空。
缓冲区列表:当缓冲区分配给(dev,blk)时,它会被插入设备表的dev_list中。如果缓冲区当前正在使用,则会将其标记为BUSY(繁忙)并从空闲列表中删除。
PV算法
BUFFER *getb1k(dev,blk):
while(1){
P(free);
//get a free buffer first
if (bp in dev_1ist){
if (bp not BUSY){
remove bp from freelist;
P(bp);
// lock bp but does not wait
return bp;
// bp in cache but BUSY
V(free);
// give up the free buffer
P(bp);
// wait in bp queue
return bp;
// bp not in cache,try to create a bp=(dev,blk)
bp = frist buffer taken out of freelist;
P(bp);
// lock bp,no wait
if(bp dirty){
awzite(bp);
// write bp out ASYNC,no wait
continue;
// continue from (1)
reassign bp to(dev,blk);
// mark bp data invalid,not dir
return bp;
// end of while(1);
brelse(BUFFER *bp),
{
iF (bp queue has waiter)( V(bp); return; }
if(bp dirty && free queue has waiter){ awrite(bp);zeturn;}
enter bp into(tail of) freelist;V(bp);V(free);
}
问题与解决思路
从磁盘到缓冲区的数据读写是否也由CPU完成?
如果每次读缓冲区都没有对应的数据,是否相当于直接磁盘I/O?
数据的换入换出算法有哪些?
实践内容
setvbuf()
int setvbuf(FILE *stream, char *buffer, int mode, size_t size);
模式 | 描述 |
---|---|
_IOFBF | 全缓冲:对于输出,数据在缓冲填满时被一次性写入。对于输入,缓冲会在请求输入且缓冲为空时被填充。 |
_IOLBF | 行缓冲:对于输出,数据在遇到换行符或者在缓冲填满时被写入,具体视情况而定。对于输入,缓冲会在请求输入且缓冲为空时被填充,直到遇到下一个换行符。 |
_IONBF | 无缓冲:不使用缓冲。每个 I/O 操作都被即时写入。buffer 和 size 参数被忽略。 |