我正在尝试将文件投影到内存中以便使用它。该文件包含结构,所以我试图使用指向一个结构的开头的指针,然后读取它并修改一些变量。 问题是执行时间很长,我想使用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
答案 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);
}
感谢大家的帮助。