转自:http://blog.yufeng.info/archives/1485
Linux下的pipe使用非常广泛, shell本身就大量用pipe来粘合生产者和消费者的. 我们的服务器程序通常会用pipe来做线程间的ipc通讯. 由于unix下的任何东西都是文件,只要是文件,在读取的时候,,就会设置last access time, 所以pipe也不例外., 但是这个时间对我们没有意义 如果pipe使用的非常频繁的时候会碰到由于设置访问时间导致的性能问题. 这个开销远比pipe读写的本身开销大. 相比文件读写的开销, atime微不足道,但是对pipe来讲就不同了.
这个事情是上次和多隆同学在把玩他的网络框架的时候,无意发现的.
我们来分析下pipe的这部分代码:
pipe_read( struct kiocb *iocb, const struct iovec *_iov, |
unsigned long nr_segs, loff_t pos) |
我们可以看到在pipe读的时候要设置 file_accessed时间的,接着:
extern void touch_atime( struct vfsmount *mnt, struct dentry *dentry); |
static inline void file_accessed( struct file *file) |
if (!(file->f_flags & O_NOATIME)) |
touch_atime(file->f_path.mnt, file->f_path.dentry); |
如果文件没设置 O_NOATIME就真正动手设置atime,接着:
void touch_atime( struct vfsmount *mnt, struct dentry *dentry) |
struct inode *inode = dentry->d_inode; |
if (inode->i_flags & S_NOATIME) |
if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)) |
if (mnt->mnt_flags & MNT_NOATIME) |
if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) |
now = current_fs_time(inode->i_sb); |
if (!relatime_need_update(mnt, inode, now)) |
if (timespec_equal(&inode->i_atime, &now)) |
mark_inode_dirty_sync(inode); |
我们可以看出上面的流程还是比较复杂的,开销也很大.
我们来演示下:
#include <linux/unistd.h> |
static void *rp_entry(void *arg) { |
while (1 == read (fds[0], c, 1)) { |
fprintf(stderr, "pipe read ok\n" ); |
int main(int argc, char *argv[]) { |
fprintf(stderr, "usage: pipe_test NNNNNN\n" ); |
//fcntl(fds[0], F_SETFL, O_NOATIME); |
pthread_create(&rp, NULL, rp_entry, NULL); |
fprintf(stderr, "pipe write %ld..." , n); |
for (i = 0; i < n; i++) { |
$ gcc -D_GNU_SOURCE pipe_test.c -lpthread |
$ sudo opcontrol --setup --vmlinux=/usr/lib/debug/lib/modules/2.6.18-164.el5/vmlinux |
$ sudo opcontrol --init && sudo opcontrol --reset && sudo opcontrol --start |
$ sudo opcontrol -- shutdown |
samples % app name symbol name |
378654 92.7742 vmlinux .text.acpi_processor_idle |
12978 3.1797 vmlinux current_fs_time |
2530 0.6199 vmlinux thread_return |
2345 0.5745 vmlinux touch_atime |
2253 0.5520 vmlinux .text.acpi_safe_halt |
1597 0.3913 vmlinux timespec_trunc |
1368 0.3352 vmlinux file_update_time |
1253 0.3070 vmlinux __mark_inode_dirty |
901 0.2208 vmlinux pipe_writev |
768 0.1882 vmlinux __mutex_lock_slowpath |
763 0.1869 vmlinux try_to_wake_up |
270 0.0662 vmlinux copy_user_generic_unrolled |
254 0.0622 vmlinux acpi_set_register |
254 0.0622 vmlinux system_call |
233 0.0571 vmlinux pipe_readv |
188 0.0461 vmlinux dnotify_parent |
167 0.0409 vmlinux mutex_unlock |
我们可以看到touch_atime的开销很大,远比pipe的读写大.
这次把这行注释去掉: fcntl(fds[0], F_SETFL, O_NOATIME); 指示pipe在读的时候不更新atime,看下效果:
samples % app name symbol name |
599018 95.2466 vmlinux .text.acpi_processor_idle |
4140 0.6583 vmlinux .text.acpi_safe_halt |
3281 0.5217 vmlinux thread_return |
2812 0.4471 vmlinux current_fs_time |
2615 0.4158 vmlinux file_update_time |
1790 0.2846 vmlinux __mutex_lock_slowpath |
1657 0.2635 vmlinux timespec_trunc |
1341 0.2132 vmlinux try_to_wake_up |
1281 0.2037 vmlinux mutex_unlock |
1080 0.1717 vmlinux mutex_lock |
1001 0.1592 vmlinux pipe_readv |
925 0.1471 vmlinux pipe_writev |
这下看不到touch_atime了,开销省了,对于高性能服务器是很重要的.
小结: 细节很重要,记得开文件open的时候设置O_NOATIME或者用fcntl搞定它.
祝玩得开心!
- ecmall在linux下的安装注意事项(转)
今天跟ecshop客服胡娇沟通后知道ecmall基本配置是[LAMP] linux+apache+mysql+php,然后自己开始在linux下安装ecmall并做迁移,整理了一下中间碰到的问题.1. ...
- ecmall在linux下的安装注意事项(转) ----ecmall系统迁移
linux+apache+mysql+php,然后自己开始在linux下安装ecmall并做迁移,整理了一下中间碰到的问题.1.系统选择的环境是centos6.3,安装不做介绍. 2.安装 MySQL ...
- anaconda在linux下的安装注意事项
不应该做什么 官网原文: Installation Instructions Linux Install These instructions explain how to install Anaco ...
- linux 下SPI通信注意事项(待续)
一.2台Linux设备之间使用SPI通信 1.标准Linux只支持Master 模式.但是可以在驱动中修改为Slave模式: 2.硬件SPI可能支持Slave模式,也可能不支持.这个要提前确认好: 3 ...
- 在linux下用tomcat部署java web项目的过程与注意事项
在linux下用tomcat部署java web项目的过程与注意事项 一.安装JDK 到http://www.oracle.com/technetwork/java/javase/downloads/ ...
- linux 下 tomcat 运行报错 Broken pipe
linux 下 tomcat 运行报错 Broken pipe 感谢:http://hi.baidu.com/liupenglover/blog/item/4048c23ff19f1cd67d1e71 ...
- linux下高并发网络应用注意事项
本文转自:http://www.blogjava.net/bacoo/archive/2012/06/11/380500.html linux下高并发网络应用注意事项 vi /etc/sysctl.c ...
- 在linux下用tomcat部署java web项目的过程与注意事项(转)
在linux下用tomcat部署java web项目的过程与注意事项一.安装JDK到http://www.oracle.com/technetwork/java/javase/downloads/in ...
- linux下php中文UTF-8转换Unicode方法和注意事项
先说下遇到问题:1.php没有内置unicode_ecode函数可以直接使用 2.网上很多资料都是用$str = iconv($encoding, 'UCS-2', $str); window下转换出 ...
随机推荐
- C#高级编程笔记 Day 3, 2016年9月 8日 抽象类
1.虚方法:把一个基类函数声明为 virtual,就可以在任何派生类中重写该函数. 2.在Java 中所有函数都是虚拟的,但是在C# 中,C# 要求在派生类的函数重写另一个函数时,要使用 overri ...
- XSS Filter绕过
之前挖到某金融网站的xss 但是困于xss filter无奈不好下手.只能在火狐下弹窗. 以下该图是我的测试. 后来发给一个Invoker哥们儿.成功给我发来payload成功绕过了XSS Filte ...
- 剑指Offer 栈的压入、弹出序列
题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序 ...
- Android 解析JSON格式数据
比起XML,JSON主要优势在于它的体积更小,在网络上传输的时候可以更省流量.但缺点在于,它的语义性较差,显示不如XML直观. JSON格式 : { "name_A" : &qu ...
- [CQOI2011]动态逆序对
(又是一道树套树……自己真是玩疯了……) (题意略) 从网上也看过题解,好像解法很多……比如CDQ+树状数组,树状数组套主席树,树状数组套平衡树……我用的是树状数组套splay. (我会说是因为我不会 ...
- 如何优雅的使用 phpStorm 开发工具
按照惯例依然是从百科上复制一条简介: PhpStorm 是 JetBrains 公司开发的一款商业的 PHP 集成开发工具.PhpStorm可随时帮助用户对其编码进行调整,运行单元测试或者提供可视化d ...
- Resizing the disk space on Ubuntu Server VMs running on VMware ESXi 5
from: http://www.joomlaworks.net/blog/item/168-resizing-the-disk-space-on-ubuntu-server-vms-running- ...
- C# 数组、多维数组(矩形数组)、锯齿数组(交叉数组)
数组是变量的索引列表,可以在方括号中指定索引来访问数组中的各个成员,其中索引是一个整数,从0开始. 一维数组 多维数组(矩形数组) 数组的数组(锯齿数组) 数组必须在访问之前初始化,数组的初始化有两种 ...
- 【leetcode】Recover Binary Search Tree
Recover Binary Search Tree Two elements of a binary search tree (BST) are swapped by mistake. Recove ...
- 3.SpringMVC修改配置文件路径和给界面传递数据
1.修改配置文件路径 达到 配置多文件的目的 web.xml文件中基础配置有springMVC配置的servlet路径 <servlet-name>SpringMVC</serv ...