使用readahead()读取函数时printf()增加I / O。 为什么?

我有一个SMB服务器在Linux(而不是SAMBA)和读取请求(函数)我使用readahead()函数。 我正在循环读取一个24KB的文件,客户端要求使用4KB的帧大小(循环中的6个请求)读取文件。

事情是当我使用printf()为每读我得到20%以上的I / O! 我不明白为什么。

这是代码示例:

typedef struct _MYFile /* file descriptor */ { FILE* file; /* underlying file handle */ chat* fileBuf[24*1024]; uint64 fileId; /* file Id */ uint64 fileOffset; /* the file offset */ uint64 readAHeadOffset; /* the read a head offset */ uint64 readAHeadLength; /* length of the read a head frame */ }MYFile 

创build文件:(文件保存在我的数据库中)

 void create() { MYFile file; file.file = fopen(name, "w+"); file.readAHeadOffset = 0; file.readAHeadLength = 0; file.fileId = 1; updateDB(file) setvbuf(file.file, file.fileBuf, _IOFBF, sizeof(file.fileBuf)); } 

现在我正在读取请求:

 void read(uint32 size, uint64 offset, uint64fileId, char* readBuf) { MYFile * file; file = getFileFromDB(fileId); /* position to the offset */ if (file->offset != offset) lseek(fileno(file->file), (off_t)offset, SEEK_SET); if (0 == file->readAHeadLength) { readahead(file->file, 0, 0, size * 6); file->readAHeadLength = params->length * 6; } //printf("print\n"); fread(fileno(file->file), readBuf, size); } 

所以readahead()只调用一次。 *与printf(“打印\ n);我得到约16000 I / O,不只有大约14000。

**即使我不使用readahead(),性能也会变好。 ***当我添加printf()write()函数时,我有同样的问题。
任何人都可以启发我?

谢谢你的头:)

编辑1:

我通过putty.exe(ssh:22)连接到Linux,每个“printf”消息都通过networking发送,并且打印出现在我的terminal上。 所以我的猜测是“printf”正在做一个系统调用,并使我的消息被发送,而不是等待(我认为)内核超时发送。

问题是什么“printf”做什么,我怎么可以模仿它来增加I / O的数量。

编辑2:(更多信息)

我的服务器在一个线程中接收请求并在另一个线程中响应。 我正在使用线程池的pthread-s接收和发送。 performance并不糟糕,但是…

当我在一个线程中执行相同的algorithm(MULTITHREAD未定义),以便recvs和发送都在同一个工作线程中时,我的应用程序运行速度提高了大约10%。

奇怪的是,当我使用单独的线程(worker和operation),但在任何操作中都包含printf时,性能提高了20% (提高 – 不下降) 。 我的printfs通过SSH。(*)

(数据包分析显示了大约100微秒的ACK响应延迟(不是单独的ACK),这种延迟不会发生在printf上,也不会发生在单线程模式下,看起来SSH似乎在TCP堆栈中触发了某些东西。

我试图在每个recv()后使用TCP_QUICKACK选项,但性能下降!(**)我正在使用Centos7。 该应用程序是非常并发的 – 这是SMB服务器。

algorithm如下:一个线程用epoll_wait()获取消息,然后执行第一个工作线程,该线程parsing消息并启动操作线程(创build/读取/写入等)。

主线:

 static void mainThreadBodySocketTransport(CSTransport * transport) { struct epoll_event e; int res; while (true) { void * context = NULL; /* to pass to thread */ res = epoll_wait(transport->epoll, &e, 1, (int)*60 * 12 * 1000)); if (res == 1) { *context = e.data.ptr; } /* wrapper to execute the worker thread */ cmThreadPoolExecute(transport->threadPool, context); } } 

工作者线程

 static void threadBodySocketTransport(void * context) { msgBuffer * message; message = parseMSG(context); switch (message->cmd) { case WRITE: doWriteOp(message); break; case READ: doReadOp(message); break; case CREATE: doCreateOp(message); break; } } void doWriteOp(msgBuffer * message) { #ifdef MULTITHREAD /* wrapper to execute the worker thread */ cmThreadPoolExecute(threadPoolWrite, (void *)message); #else /* write to file */ threadBodyWrite(message); #endif } 

操作线程

 static void threadBodyWrite(void * context) { msgBuffer * message = (msgBuffer *)context; int fd; . .(get the fd) . /* printf("w\n");*/ write(fd, message->write.data , message->write.len); sendResponse(message->cmd, true); } 

pthread创build

 void threadStart(SYThread *taskIdPtr, void (*startpoint)(void), NQ_BOOL background) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(taskIdPtr, &attr, (void * (*)(void *))startpoint, NULL) pthread_attr_destroy(&attr); } 

也许我需要使用不同的线程属性?

请帮忙。

谢谢。