使用mmap将文件投影到内存中

时间:2009-11-15 13:56:17

标签: c file mmap

我正在尝试将文件投影到内存中以便使用它。该文件包含结构,所以我试图使用指向一个结构的开头的指针,然后读取它并修改一些变量。 问题是执行时间很长,我想使用mmap时间会更少。 这是代码,有什么建议吗?

#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

int revisanotas(int fd)
{
int nbytes=1;
int nbytese=0;
int i=0;
int n=0;
struct stat datos;
fstat(fd, &datos);
evaluacion buf;
evaluacion* buffer=mmap(0,datos.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
int actual = read(fd,buffer,datos.st_size);
{
i++;
if (buffer[i].notamedia >= 4.5 && buffer[i].notamedia < 5)
{
n=n+1;
printf("Notamedia = %f\n",buffer[i].notamedia);

buffer[i].notamedia=5;
}

}while (i<(datos.st_size/(sizeof(evaluacion))));
return

5 个答案:

答案 0 :(得分:2)

首先,请告诉我们evaluacion被定义为什么,并将do放在那里与while匹配;我假设它正好在“int actual”行之后。

其次,看起来你可能比需要更频繁地调用mmap();使用相同的revisanotas()调用fd的频率是多少? mmap调用本身很慢,如malloc;速度是指您使用映射文件时的情况,在本例中是buffer指向的数据。

第三,在循环外部计算datos.st_size/(sizeof(evaluacion))并更改while子句以进行比较。当前代码看起来像是在循环中每次迭代执行一次除法,并且除法很慢。

看看是否有帮助。

答案 1 :(得分:2)

不需要拨打read()Mmap() 文件内容映射到内存中 - 这就是为什么它通常比使用read()读取整个文件更快的原因。您应该可以完全删除对read()的呼叫。但是你的代码还有其他一些问题。

如果要将修改实际反映在磁盘文件中,则应调用msync(buffer, dataos.st_size, MS_SYNC)。完成后,调用munmap(buffer, dataos.st_size)以释放共享内存段。将msync()视为与fflush()等效的共享内存,munmap()close()类似。 munmap()close()之间的主要区别在于前者不会刷新缓冲区或同步到磁盘,因此您必须自己执行此操作。

答案 2 :(得分:0)

Thanks mike for the answer, the struct is something like this and it's defined in a header file: 

struct evaluacion 
{ char id[16]; 
 char apellido1[32]; 
char apellido2[32]; 
char name[32]; float nota1p; 
float nota2p; 
float notamedia; 
char photofilename[20]; 
int photosize; 
char photodata[16000]; 
}; 

只有一个fd,只有一个文件打开,但很多结构内部

答案 3 :(得分:0)

我认为我正在取得一些进展,但似乎我没有修改文件。如果我运行程序一次,它会检测到32个变量被修改,但如果我运行两次仍然相同,那么它应该被修改:(

现在执行时间不错我认为

int revisanotas(int fd)
{
int i=0;
int n=0;
struct stat datos;
fstat(fd, &datos);
int num=datos.st_size/(sizeof(evaluacion));
evaluacion buf;
evaluacion* buffer=mmap(0,datos.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
do
{
i++;
if (buffer[i].notamedia >= 4.5 && buffer[i].notamedia < 5)
{
n=n+1;

buffer[i].notamedia=5;
}
msync(&buffer[i],sizeof(buffer[i]),MS_SYNC);
}while (i<(num));
munmap(buffer,datos.st_size);
return(n);
}

答案 4 :(得分:0)

我认为现在正在工作:),代码如下。如果你看错了,请评论:

int revisanotas(int fd)
{
int i=0;
int n=0;
struct stat datos;
fstat(fd, &datos);
int num=datos.st_size/(sizeof(evaluacion));

evaluacion* buffer=mmap(0,datos.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
do
{
i++;
if (buffer[i].notamedia >= 4.5 && buffer[i].notamedia < 5)
{
n=n+1;
buffer[i].notamedia=5;
}

}while (i<(num));
int r=munmap(&buffer[0],datos.st_size);

return(n);
}

感谢大家的帮助。