前面两篇关于文件系统的预读我们通过实例阐述了应用程序的顺序读而触发操作系统对文件大小预取情况,本篇博客我们主要描述预读如何解决交织读的问题。所谓的交织读指的是多线程(进程)读同一个打开的文件描述符,单个线程的顺序读在操作系统看来可能会变成随机读。同样我们还是结合实例来分析。
事例代码
{
......
f = open("file", ......)
pthread_create(read_file_1, f, ...)
pthread_create(read_file_2, f, ...)
......
}
read_file_1(f)
{
lseek(f, 0, SEEK_SET);
read(f, ..., 2 * 4096);
read(f, ..., 4 * 4096)
read(f, ..., 16 * 4096)
}
read_file_2(f)
{
lseek(f, 128 * 4096, SEEK_SET);
read(f, ..., 2 * 4096);
read(f, ..., 4 * 4096)
read(f, ..., 16 * 4096)
}
事例代码中创建了两个线程同时读文件file,每个线程均是顺序读,让我们看看操作系统的预读是如何处理这种情况的。因为多线程的执行顺序可能是多种多样的,我们只列举一种执行流并解释,线程1 read 1,线程2 read 1,线程2 read 2,线程1 read 2,线程1 read 3,线程2 read3。
线程1 Read 1
线程1读文件的前两个页面,由于尚未缓存命中,因此会触发文件系统的一次同步预读,确定预读窗口为(ra->start, ra->size, ra->async_size) = (0, 4, 2),形成的预读窗口如下: