日期:2014-05-16  浏览次数:20514 次

Linux内核设计的艺术-关于缓冲块的进程等待队列

    进程A是一个读盘进程,目的是将hello.txt文件中的100字节读入buffer[100]。

    代码如下:

void FunA();
void main()
{
	...
	FunA();
	...
}

void FunA()
{
	char buffer[100];
	int i,j;
	int fd = open("/mnt/user/user1/user2/hello.txt",O_RDWR,0644);
	read(fd,buffer,sizeof(buffer));
	close(fd);
	
	for(i=0;i<1000000;i++)
	{
		for(j=0;i<100000;j++)
		{
			;
		}
	}
}

      进程B也是一个读盘进程,目的是将hello.txt文件中的200字节读入buffer[200]。

void FunB();
void main()
{
	...
	FunB();
	...
}

void FunB()
{
	char buffer[200];
	int i,j;
	int fd = open("/mnt/user/user1/user2/hello.txt",O_RDWR,0644);
	read(fd,buffer,sizeof(buffer));
	close(fd);
	
	for(i=0;i<1000000;i++)
	{
		for(j=0;i<100000;j++)
		{
			;
		}
	}
}
   

      进程C是一个写盘进程,目的是往hello.txt文件中写入str[]中的字符“ABCDE”。

      代码如下:

void FunC();
void main()
{
	...
	FunC();
	...
}

void FunC()
{
	char str1[]="ABCDE";
	int i,j;
	int fd = open("/mnt/user/user1/user2/hello.txt",O_RDWR,0644);
	write(fd,str1,strlen(str1));
	close(fd);
	
	for(i=0;i<1000000;i++)
	{
		for(j=0;i<100000;j++)
		{
			;
		}
	}
}

      这三个进程执行顺序为:进程A先执行,之后进程B执行,最后进程C执行。这三个进程没有父子关系。

      进程A启动后,执行open函数,最终会映射到sys_open函数区执行。

      代码路径:fs/open.c

nt sys_open(const char * filename,int flag,int mode)
{
	.../寻找空闲的file,和inode
	(current->filp[fd]=f)->f_count++;
	if ((i=open_namei(filename,flag,mode,&inode))<0) {
	        ...
	}
        ...
	f->f_mode = inode->i_mode;
	f->f_flags = flag;
	f->f_count = 1;
	f->f_inode = inode;
	f->f_pos = 0;
	return (fd);
}
       之后开始执行read函数,read函数最终会映射到sys_read()函数去执行。

       代码路径:fs/read_write.c

int sys_read(unsigned int fd,char * buf,int count)
{
	struct file * file;
	struct m_inode * inode;

	if (fd>=NR_OPEN || count<0 || !(file=current->filp[fd]))
		return -EINVAL;
	...
	inode = file->f_inode;
	...
	if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode)) {
		if (count+file->f_pos > inode->i_size)
			count = inode->i_size - file->f_pos;
		if (count<=0)
			return 0;
		return file_read(inode,file,buf,count);
	}
	printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode);
	return -EINVAL;
}
       之后sys_read函数调用file_read()来读取文件内容。

       代码路径:fs/file_dev.c

int file_read(struct m_inode * inode, struct file * filp, char * buf, int count)
{
	int left,chars,nr;
	struct buffer_head * bh;

	if ((left=count)<=0)
		return 0;
	while (left) {
		if ((nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE))) {
			if (!(bh=bread(inode->i_dev,nr)))
				break;
		} else