怎样提高写文件的速度
情况是这样的:我在写一个从网络接收报文,然后把报文存在一个文件里面的程序。报文发送的间隔达到了几十微秒,时间非常短。
这部分代码如下:
if(*counter==1)
{
if((fd=open("/home/goosefile.txt",O_RDWR|O_CREAT))<0)
{
DBGL("file open failed\n");
exit(1);
}
}
if((file_w=fork())<0)
{
DBGL("fork file operation failed\n");
exit(1);
}
if(file_w>0)
{
waitpid(file_w,NULL,0);
++file_count;
printf("countnum is %lu\n",file_count);//这是计算接收到的报文数量
}
else if(file_w==0)
{
lseek(fd,10,SEEK_END);
if((writefd=write(fd,packet,pkthdr->len))<0)
{
DBGL("file write failed\n");
exit(1);
}
exit(1);
}
文件只在第一个报文到来的时候打开一次,每次来一个报文都开辟一个进程,主进程等待子进程结束,子进程退出。 但是测试结果非常不理想:发10000个报文只能接收到7000个左右,而且如果提高发送速率的话,收到的报文就更少了。
就是说,现在如何提高写文件的速度。
[解决办法]
用标准I/O函数,,fprintf,fscanf,fwrite,fread,fopen,fclose,,,这个自带缓冲。
或者如果你非要用write,read读写文件的话,就自己加个缓存,,每4KB或者8KB时一次性写入。这样磁盘I/O效率最高。而用标准I/O函数就不用考虑这个问题了,因为他自带缓冲
还有你不应该使用接收一个报文就fork一下,,fork的开锁是比较大的。。
应该使用单消费者/单生产者的模型或者单生产者/多消费者模型。。一个线程负责接收报文放到公共缓冲区,另一个(或多个)线程负责从公共缓冲中取报文,然后fwrite到文件。 单生产者一般用环形缓冲配合锁实现,,自己搜索下,
[解决办法]
网络I/O线程负责收,直接丢到链式队列里,让文件I/O线程去顺序写。
方案1:直接mutex+cond+queue,网络I/O线程只管往queue里丢了就signal唤醒cond,无须判断队列容量,直到撑爆内存core掉为止(可做内存池控制进程内存low-waterline防core,不过会导致丢弃部分报文,也可直接控制队列容量,丢弃报文即可,但不可挂起cond导致阻塞网络I/O),文件I/O就是取了去写,队列空就挂起cond。
方案2:epoll+pipe/socketpair+1字节做文件I/O实践触发, 写pipe失败则丢弃报文即可,或者和上面一样直接控制队列尺寸即可.
[解决办法]
楼上都有大的建议,我说一句,就是要接受线程 与 写文件线程分开。 还有如果不知道你写的文件内容以后只是留作记录。为什么不考虑共享缓冲区代替反复写硬盘,把受到的内容放在内存中,退出时统一刷到硬盘。
[解决办法]