系统软件性能调优策略(一)——通过有名管道FIFO来检测消息队列中是否可读
2010-04-19 14:04
260 查看
在基于网络的开发中,socket的发送、接收状态,可以通过select来进行检测。但如果又有其他的业务要处理,比如处理消息队列,则可能会出现两难的情况:
1)tmval.tv_usec = 20;
select(sockid,,,,&tmval);
select等待指定时间,如果期间有消息需要处理,则会造成CPU资源的浪费、业务流程处理的延时,而产生性能降低;
2)select(sockid,,,,0)
NO_WAIT方式,则可能会造成系统空转,CPU无谓负荷高,造成系统资源的浪费。
一种好的处理方式是,借用复用I/O的技术,将队列的读取转换为有名管道FIFO的状态检测,具体如下:
这样,即使是在以下任何一种情况下,都会使得select被激活并返回,就不会造成CPU资源的效率,并且系统的性能将大大得到提高。
备注:
此法,只适用于Unix。由于Windows上的select仅仅对socket有效,所以此法不适用。
1)tmval.tv_usec = 20;
select(sockid,,,,&tmval);
select等待指定时间,如果期间有消息需要处理,则会造成CPU资源的浪费、业务流程处理的延时,而产生性能降低;
2)select(sockid,,,,0)
NO_WAIT方式,则可能会造成系统空转,CPU无谓负荷高,造成系统资源的浪费。
一种好的处理方式是,借用复用I/O的技术,将队列的读取转换为有名管道FIFO的状态检测,具体如下:
一、有名管道的准备: A)创建有名管道 #define MY_FIFO_NAME "myfifo" fp = mkfifo(FifoFile, mode); B)向队列中写入消息的同时,向该管道内写入1个字符 fifoout = open(FifoFile, O_RDWR | O_NONBLOCK); #ifndef WIN32 do{ /* 每次向队列中写入消息时,也向FIFO管道中写入一个字符 */ fifoRet = write(fifoout, "T", 1); if(fifoRet <= 0){ /* 屏蔽中断信号 */ if (errno==EAGAIN || errno==EWOULDBLOCK || errno==EINTR) continue; else{ return(-1); } } else break; }while(1); close(fifoout); #endif C)在读取消息队列后,也读取FIFO中的一个字符 #ifndef WIN32 do{ fifoRet = read(fifoout, fifoStr,1); if(fifoRet<=0){ /* 屏蔽中断信号 */ if (errno==EAGAIN || errno==EWOULDBLOCK || errno==EINTR) continue; else{ fprintf(stderr,"read fifo fail, fifoout=%d, syserr=%d/n", fifoRet, errno); break; } } else break; }while(1); #endif D)系统退出时,删除管道FIFO fifoRet = unlink(FifoFile); 二、有名管道的的I/O复用 A)将有名管道的描述符添加到readfds中 #ifndef WIN32 /* 将有名管道myfifo的fd追加到readfds中,以进行select */ FD_SET(fifoout, &readfds); #endif B)进行select,并对结果进行判断 tmval.tv_sec = 0; tmval.tv_usec = 30; /* miniseconds, 30毫秒*/ ret = select(FD_SETSIZE,&readfds,&writefds, (fd_set *)0, (struct timeval *)&tmval); /* 只有fifo可读时,才进行网路发送 */ if(ret >0 && FD_ISSET(fifoout,&readfds)) msgrcv(...);
这样,即使是在以下任何一种情况下,都会使得select被激活并返回,就不会造成CPU资源的效率,并且系统的性能将大大得到提高。
备注:
此法,只适用于Unix。由于Windows上的select仅仅对socket有效,所以此法不适用。
相关文章推荐
- 系统软件性能调优策略(一)——通过有名管道FIFO来检测消息队列中是否可读
- 通信方式详解,无名管道pipe,有名管道fifo,共享内存share memory,消息队列msg
- Day31、未决信号、有名管道、IPC进程间通讯(消息队列)
- 15章 进程间通信之消息传递(管道、FIFO、消息队列)
- linux 系统编程-学习笔记10--进程间通信--管道/FIFO/消息队列/
- 笔记:进程间通信——消息传递(管道、FIFO、posix消息队列)
- 共享内存和消息队列,FIFO,管道传递消息的区别
- 管道/FIFO/共享内存/消息队列/信号
- Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存
- 现在最常用的进程间通信的方式有:管道,信号,信号量,消息队列,共享内存。
- 扩展方法检测客户端队列是否存在
- C118 smsweb: 通过日志关键字检测判断obb程序是否工作正常_20160617_七侠镇莫尛貝
- linux c之通过消息队列实现进程通信
- linux 练习七 线程键用有名管道FIFO通信
- Linux进程间通信方式--信号,管道,消息队列,信号量,共享内存
- 通过有名管道实现简单的文件传输
- Linux--进程间通信(管道及有名管道FIFO)(转)
- 汇款诈骗通话检测技术:通过检测是否“过于相信对方”来防止被骗
- 进程间通信的方式——信号、管道、消息队列、共享内存
- 通过定时器来定时检测是否存在U盘