<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://www.jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://www.jackxiang.com/post//</link>
<title><![CDATA[[Nginx上传]对Nginx上传进行代码跟踪时对glibc的 Asynchronous I/O 写性能测试这nginx上传模块研究使用。]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[Web服务器]]></category>
<pubDate>Thu, 09 May 2013 04:20:50 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	背景：近来对Nginx的上传模块这一块，Flash上传时进度条都过了，但是那个文件还没有出现，一会儿后才出现那个文件，并慢慢增大，我用的是Nginx的上传插件，这种问题怎么去查？我刚用了strace，我在想它是把上传的东东放在哪儿去了呢？<br/>http://www.grid.net.ru/nginx/download/nginx_upload_module-2.2.0.tar.gz<br/>Rango&nbsp;&nbsp;上午 11:56:57<br/>用apache来做吧，apache是交给php来处理的，<br/>回忆未来-向东-Jàck&nbsp;&nbsp;下午 12:01:57<br/>嗯，我再看看，兄弟觉得Apache下的PHP比起Nginx的PHP在上传一块有更高的效率是么？<br/>Rango&nbsp;&nbsp;下午 12:02:23<br/>都差不多吧<br/>apache比较成熟<br/><br/>=================================================================================<br/>Rango&nbsp;&nbsp;下午 01:45:42<br/>你看下 man pwrite<br/>回忆未来-向东-Jàck&nbsp;&nbsp;下午 01:55:19<br/>好看到了，这个PHP上传大文件和Nginx上传大文件，是先接进来放到内存后，在写到文件里吧？<br/>Rango&nbsp;&nbsp;下午 01:55:30<br/>嗯，是的，都是这样做了<br/>pwrite就是相当于 fseek + fwrite<br/>回忆未来-向东-Jàck&nbsp;&nbsp;下午 01:56:55<br/>至于内存里放在什么时候开始写，那应该是由nginx程序里的配置来实现的吧？<br/>如果我猜测没错的话<br/>=================================================================================<br/>upload_buffer_size 上传缓冲区大小<br/>upload_max_file_size 指定上传文件最大大小，软限制。client_max_body_size硬限制。<br/>upload_limit_rate 上传限速，如果设置为0则表示不限制。<br/>upload_pass_args 是否转发参数。<br/>=============================================================================<br/><textarea name="code" class="php" rows="15" cols="100">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location /upload &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upload_pass&nbsp;&nbsp;&nbsp;&nbsp; /up.php;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upload_cleanup 400 404 499 500-505;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#upload_store&nbsp;&nbsp;&nbsp;&nbsp;/data/app/test.local/upload_tmp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upload_store&nbsp;&nbsp;&nbsp;&nbsp;/tmp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upload_store_access user:r;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upload_limit_rate 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upload_buffer_size 100k;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upload_max_file_size 1024m;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;client_max_body_size 1024m;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upload_set_form_field &quot;$&#123;upload_field_name&#125;_name&quot; $upload_file_name;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upload_set_form_field &quot;$&#123;upload_field_name&#125;_content_type&quot; $upload_content_type;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upload_set_form_field &quot;$&#123;upload_field_name&#125;_path&quot; $upload_tmp_path;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upload_aggregate_form_field &quot;$&#123;upload_field_name&#125;_md5&quot; $upload_file_md5;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upload_aggregate_form_field &quot;$&#123;upload_field_name&#125;_size&quot; $upload_file_size;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;upload_pass_form_field &quot;^.*$&quot;;


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#upload_pass_form_field &quot;^pid$&#124;^tags$&#124;^categoryid$&#124;^title$&#124;^userid$&#124;^user_id$&#124;^is_original$&#124;^upload_file_name$&#124;^upload_file_content_type$&#124;^upload_file_path$&#124;^upload_file_md5$&#124;^upload_file_size$&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location ~ .*&#92;.(php&#124;php5)?$ &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fastcgi_pass&nbsp;&nbsp;127.0.0.1:9000;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fastcgi_index index.php;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include fcgi.conf;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/><br/>=============================================================================<br/>ack 1460:<br/>第一个报文的TCP头里通过MSS这个可选项告知对方本端能够接收的最大报文（当然，这个大小是TCP净荷的大小），以太网上这个值一般设置成1460，因为1460Byte净荷+20Byte TCP头+20Byte IP头 ＝ 1500字节，正好符合链路层最大报文的要求。<br/>http://wenku.baidu.com/view/d77645d533d4b14e84246800.html<br/><br/><br/>strace -p 7269&nbsp;&nbsp;-o s.log<br/>Nginx太多了进程：<br/>[root@test tmp]# cat strace.sh <br/><textarea name="code" class="php" rows="15" cols="100">
nohup strace -p&nbsp;&nbsp;434&nbsp;&nbsp;-o s1.log&nbsp;&nbsp;&amp;
nohup strace -p&nbsp;&nbsp;435&nbsp;&nbsp;-o s2.log&nbsp;&nbsp;&amp;
nohup strace -p&nbsp;&nbsp;436&nbsp;&nbsp;-o s3.log&nbsp;&nbsp;&amp;
nohup strace -p&nbsp;&nbsp;437&nbsp;&nbsp;-o s4.log&nbsp;&nbsp;&amp;
nohup strace -p&nbsp;&nbsp;438&nbsp;&nbsp;-o s5.log&nbsp;&nbsp;&amp;
nohup strace -p&nbsp;&nbsp;439&nbsp;&nbsp;-o s6.log&nbsp;&nbsp;&amp;
nohup strace -p&nbsp;&nbsp;440&nbsp;&nbsp;-o s7.log&nbsp;&nbsp;&amp;
nohup strace -p&nbsp;&nbsp;441&nbsp;&nbsp;-o s8.log&nbsp;&nbsp;&amp;
</textarea><br/><br/>都是读4096个字符一次写，pwrite64和这个相当应该：<br/> ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);<br/><br/><br/>原型&nbsp;&nbsp;char *&nbsp;&nbsp;fgets(char * s, int n,FILE *stream);<br/>&nbsp;&nbsp;&nbsp;&nbsp;参数：<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s: 字符型指针，指向存储读入数据的缓冲区的地址。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n: 从流中读入n-1个字符<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stream ： 指向读取的流。<br/><br/><br/>函数原型<br/>ssize_t pwrite(intfd, const void *buf, size_tcount, off_toffset)；<br/>编辑本段<br/>用法<br/>返回值：成功，返回写入到文件中的字节数；失败，返回-1；<br/>参数：<br/>(1) fd：要写入数据的文件描述符<br/>(2) buf：数据缓存区指针，存放要写入文件中的数据<br/>(3) count：写入文件中的数据的字节数<br/>(4) offset：写入起始地址的偏移量，写入地址=文件开始+offset。注意，执行后，文件偏移指针不变<br/><br/>什么是字节，字节数相关学习备案：<br/>字节（Byte 发音：/‘bait/）：字节是通过网络传输信息（或在硬盘或内存中存储信息）的单位。在ASCII码中，一个英文字母（不分大小写）占一个字节的空间，一个中文汉字占两个字节的空间。符号：英文标点占一个字节，中文标点占两个字节。举例：英文句号“.”占1个字节的大小，中文句号“。”占2个字节的大小 。一个二进制数字序列,在计算机中作为一个数字单元,一般为8位二进制数，换算为十进制。最小值：0 最大值：255 。如一个ASCII码就是一个字节，此类单位的换算为： 　1KB(Kilobyte 千字节)=1024B，1MB(Megabyte 兆字节 简称“兆”)=1024KB，1GB(Gigabyte 吉字节 又称“千兆”)=1024MB，<br/>数据包是信息在通行通道上传递的形式~~<br/>字节是信息的单位~~一字节等于8个比特位！<br/>wc - c 统计字节数：<br/>[root@test ~]# cat a.txt &#124;wc -c<br/>2&nbsp;&nbsp;[里面写：a的字节数]<br/>[root@test ~]# vi a.txt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>[root@test ~]# cat a.txt &#124;wc -c<br/>8&nbsp;&nbsp;[里面写：a向东 的字节数]<br/>比特（bit）即一个二进制位&nbsp;&nbsp;例如100011就是6比特<br/>字节（byte）这是计算机中数据类型最基本的单位了，8bit 组成1byte<br/>字（word）两个byte称为一个word，所以字大小应该是16位bit，共两字节。（Shell里的）<br/>双字（double word 简写为DWORD）见名知意，两个字，四个字节，32bit。<br/>C语言：char 字符型&nbsp;&nbsp;占1byte 即8位，一个char型数据（例如：a、#、！之类的）用了1个字节来存储：<br/><textarea name="code" class="c" rows="15" cols="100">
#include &lt;stdio.h&gt;
int main()
&#123;
 char a=&#039;a&#039;;
 printf(&quot;size of char a=%d&#92;n&quot;,sizeof(a));
 printf(&quot;size of char =%d&#92;n&quot;,sizeof(char));
&#125;
</textarea><br/>root@192.168.137.128:~# ./a.out <br/>size of char a=1<br/>size of char =1<br/><br/><br/><br/>中间断开测试,浏览器突然断开：<br/>accept4(5, &#123;sa_family=AF_INET, sin_port=htons(58438), sin_addr=inet_addr(&quot;192.168.137.1&quot;)&#125;, [16], SOCK_NONBLOCK) = 3<br/>epoll_ctl(13, EPOLL_CTL_ADD, 3, &#123;EPOLLIN&#124;EPOLLET, &#123;u32=3039736117, u64=722997274181808437&#125;&#125;) = 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>epoll_wait(13, &#123;&#123;EPOLLIN, &#123;u32=3039736117, u64=722997274181808437&#125;&#125;&#125;, 512, 60000) = 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>gettimeofday(&#123;1368072732, 443326&#125;, NULL) = 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>recv(3, &quot;POST /upload HTTP/1.1&#92;r&#92;nHost: tes&quot;..., 32768, 0) = 32768&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>recv(3, &quot;&#92;0&#92;1&#92;0&#92;0*0&#92;0&#92;0&#92;0&#92;2&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;1&#92;0&#92;0*0&#92;0&#92;0&#92;0&#92;2&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&quot;..., 8192, 0) = 8192&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>epoll_wait(13, &#123;&#123;EPOLLIN, &#123;u32=3039736117, u64=722997274181808437&#125;&#125;&#125;, 512, 7) = 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>gettimeofday(&#123;1368072732, 446037&#125;, NULL) = 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>epoll_wait(13, &#123;&#125;, 512, 4)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>gettimeofday(&#123;1368072732, 451445&#125;, NULL) = 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>open(&quot;/data/app/test.local/upload_tmp/0000000005&quot;, O_RDWR&#124;O_CREAT&#124;O_EXCL&#124;O_LARGEFILE, 0600) = 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>pwrite64(4, &quot;&#92;0&#92;0&#92;0&#92;24ftypisom&#92;0&#92;0&#92;0&#92;1isom&#92;0&#92;rx&#92;373moov&#92;0&#92;0&#92;0l&quot;..., 4096, 0) = 4096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>pwrite64(4, &quot;&#92;0&#92;2&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;3&#92;0&#92;0&#92;16&#92;20&#92;0&#92;0&#92;0&#92;1&#92;0&#92;0*0&#92;0&#92;0&#92;0&#92;2&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&quot;..., 4096, 4096) = 4096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>pwrite64(4, &quot;&#92;0&#92;1&#92;0&#92;0*0&#92;0&#92;0&#92;0&#92;2&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;1&#92;0&#92;0*0&#92;0&#92;0&#92;0&#92;2&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&quot;..., 4096, 8192) = 4096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/><br/>.........................................<br/><br/><br/>pwrite64(4, &quot;&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&quot;..., 4096, 7622656) = 4096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>pwrite64(4, &quot;e&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;240&#92;5&#92;343&#92;t&#92;240&#92;335d&#92;t@&#92;327d&#92;t&#92;240.&#92;341&#92;t&quot;..., 4096, 7626752) = 4096 <br/>recv(3, 0xa0a9048, 8192, 0)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = -1 EAGAIN (Resource temporarily unavailable)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>epoll_wait(13, &#123;&#123;EPOLLIN&#124;EPOLLERR&#124;EPOLLHUP, &#123;u32=3039736117, u64=722997274181808437&#125;&#125;&#125;, 512, 60000) = 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>gettimeofday(&#123;1368072745, 256485&#125;, NULL) = 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>recv(3, 0xa0a9048, 8192, 0)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = -1 ECONNRESET (Connection reset by peer)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>pwrite64(4, &quot;s&#92;0i&#92;0t&#92;0o&#92;0r&#92;0y&#92;0&#92;0&#92;0&#92;0&#92;0&#92;36&#92;0&#92;0&#92;0&#92;2&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&#92;0&quot;..., 2800, 7630848) = 2800&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>close(4)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>unlink(&quot;/data/app/test.local/upload_tmp/0000000005&quot;) = 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>write(9, &quot;2013/05/09 12:12:25 [alert] 7269&quot;..., 240) = 240&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>close(3)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>epoll_wait(13,&nbsp;&nbsp;&lt;unfinished ...&gt;&nbsp;&nbsp; <br/><br/><br/><br/><br/><br/><br/><br/><br/>测试主机是AIX6.1<br/><br/>　　测试数据是向文件中顺序写入 8K * 50000 大小的数据，生成的文件大约为390M<br/><br/>　　测试对比了两种写操作，一种是aio_write， 另一种是 pwrite64； dwFlags 是open文件时，传入的参数<br/><br/>　　第一种测试<br/><br/>　　dwFlags = O_RDWR &#124;&nbsp;&nbsp;O_LARGEFILE &#124; O_DIRECT &#124; O_CREAT &#124; O_EXCL;<br/><br/>　　pwrite64 时间 : 237 秒<br/><br/>　　aio_write 时间: 236 秒<br/><br/>　　第二种测试<br/><br/>　　dwFlags = O_RDWR &#124;&nbsp;&nbsp;O_LARGEFILE &#124; O_SYNC&nbsp;&nbsp;&#124; O_CREAT &#124; O_EXCL;<br/><br/>　　pwrite64 时间 : 560秒<br/><br/>　　aio_write 时间:&nbsp;&nbsp;567秒<br/><br/>　　第三种测试<br/><br/>　　dwFlags = O_RDWR &#124; O_LARGEFILE &#124; O_DIRECT &#124; O_SYNC&nbsp;&nbsp;&#124; O_CREAT &#124; O_EXCL;<br/><br/>　　pwrite64 时间 : 568秒<br/><br/>　　aio_write 时间:&nbsp;&nbsp;569秒<br/><br/>　　由于测试只是测试写操作，而且是顺序写，没有随机写；另一方面，没有在写操作中，加入写读作；还有就是只是对单一文件的写操作，不是多线程同时对多个文件的操作，所以测试还有很多局限性，更详细的测试需要进一步完成，还需测试不同页面大小时对性能的影响<br/><br/>　　从上面这三种测试来看，<br/><br/>　　第一，当 dwFlags 相同时， 在单文件上面，同步写（pwrite64 ）和异步写（aio_write ）差距不大，主要原因估计是glibc的底层实现也是通过pwrite64 实现的，只不过加了一个多线程，也许对多个文件时，会有一些差别。<br/><br/>　　第二，O_DIRECT 比 O_SYNC&nbsp;&nbsp;比较大的提高写性能，快了一半，<br/><br/>　　第三，O_SYNC&nbsp;&nbsp;与 O_DIRECT &#124; O_SYNC&nbsp;&nbsp;几乎相同，<br/><br/>　　下面是测试用的程序<br/><textarea name="code" class="c" rows="15" cols="100">
#include &lt;stdio.h&gt;
#include &lt;time.h&gt;
#include &lt;sys/time.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;unistd.h&gt;
#include &lt;aio.h&gt;
#include &lt;string.h&gt;
#include &lt;errno.h&gt;

typedef char _aligned_char __attribute__ ((aligned (8192)));
const int DATA_LEN = 8192;
const int DATA_SIZE = 50000;
 //_aligned_char bufferAO[8192];
&nbsp;&nbsp;char bufferAO[8192] __attribute__((aligned(4096)));
void testAIO()
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;struct timeval start;
&nbsp;&nbsp;&nbsp;&nbsp;struct timeval end;
&nbsp;&nbsp;&nbsp;&nbsp;int ret;
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;//_aligned_char buffer[DATA_LEN];
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;int i = 0;
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;struct aioinit;
&nbsp;&nbsp; 
&nbsp;&nbsp;int dwFlags = O_RDWR &#124; O_LARGEFILE &#124; O_DIRECT &#124; O_SYNC&nbsp;&nbsp;&#124; O_CREAT &#124; O_EXCL;&nbsp;&nbsp;//&#124; O_NOATIME
 
&nbsp;&nbsp;dwFlags = O_RDWR &#124;&nbsp;&nbsp;O_LARGEFILE &#124; O_SYNC&nbsp;&nbsp;&#124; O_CREAT &#124; O_EXCL;
 
&nbsp;&nbsp;//aioinit.aio_threads = 10;
&nbsp;&nbsp;//aioinit.aio_num = 10;
&nbsp;&nbsp;//aio_init(&amp;aioinit);
 
&nbsp;&nbsp;int fd = open(&quot;aio_write.dat&quot;, dwFlags);
&nbsp;&nbsp;&nbsp;&nbsp;if (fd&lt;0)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;open error:&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;if (ftruncate64(fd, DATA_LEN * DATA_SIZE))
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;ftruncate64 error:&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;gettimeofday(&amp;start, NULL);
&nbsp;&nbsp; 
&nbsp;&nbsp; 
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;for (; i&lt;= DATA_SIZE; i++)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp; struct aiocb stAio;
&nbsp;&nbsp;&nbsp;&nbsp; memset(&amp;stAio, 0, sizeof(stAio));
&nbsp;&nbsp;&nbsp;&nbsp; stAio.aio_buf = bufferAO;
&nbsp;&nbsp;&nbsp;&nbsp; stAio.aio_nbytes = DATA_LEN;
&nbsp;&nbsp;&nbsp;&nbsp; stAio.aio_offset = i * DATA_LEN;
&nbsp;&nbsp;&nbsp;&nbsp; stAio.aio_fildes = fd;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp; ret = aio_write(&amp;stAio);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp; if(ret &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp; &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;aio_write error:&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp; &#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp; struct aiocb *cblist[1] = &#123;&amp;stAio&#125;;
&nbsp;&nbsp; ret = aio_error(&amp;stAio);
 
&nbsp;&nbsp; if (ret == 0) &#123;
&nbsp;&nbsp; // already completed
&nbsp;&nbsp; &#125;
&nbsp;&nbsp; else if (ret == EINPROGRESS) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;if (aio_suspend((const struct aiocb *const*)cblist, 1, NULL))
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror(&quot;aio_suspend error:&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp; &#125;
&nbsp;&nbsp; else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;aio_error error:&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;
&nbsp;&nbsp; &#125;
&nbsp;&nbsp;if (aio_return(&amp;stAio) != DATA_LEN)
&nbsp;&nbsp; &#123;
&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;aio_return error:&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp; gettimeofday(&amp;end, NULL);
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;close(fd);
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;&#92;&#92;nAIO O_DIRECT second : %d microSec : %d&#92;&#92;n&quot;, end.tv_sec-start.tv_sec, end.tv_usec-start.tv_usec);
&#125;
void test()
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;struct timeval start;
&nbsp;&nbsp;&nbsp;&nbsp;struct timeval end;
&nbsp;&nbsp;&nbsp;&nbsp;int ret;
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;//_aligned_char buffer[DATA_LEN];
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;int i = 0;
&nbsp;&nbsp; 
&nbsp;&nbsp;int dwFlags = O_RDWR &#124; O_LARGEFILE &#124; O_DIRECT &#124; O_SYNC&nbsp;&nbsp;&#124; O_CREAT &#124; O_EXCL; //&#124; O_NOATIME
 
&nbsp;&nbsp;dwFlags = O_RDWR &#124;&nbsp;&nbsp;O_LARGEFILE &#124; O_SYNC&nbsp;&nbsp;&#124; O_CREAT &#124; O_EXCL;
 
&nbsp;&nbsp;int fd = open(&quot;write.dat&quot;, dwFlags);
&nbsp;&nbsp;&nbsp;&nbsp;if (fd&lt;0)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;open error:&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
 
&nbsp;&nbsp;if (ftruncate64(fd, DATA_LEN * DATA_SIZE))
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;ftruncate64 error:&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
 
&nbsp;&nbsp;&nbsp;&nbsp;gettimeofday(&amp;start, NULL);
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;for (; i&lt;= DATA_SIZE; i++)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp; //int nLen = write(fd, bufferAO, DATA_LEN);
&nbsp;&nbsp;&nbsp;&nbsp; int nLen = pwrite64(fd, bufferAO, DATA_LEN, i*DATA_LEN );
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp; if (nLen&lt;DATA_LEN)
&nbsp;&nbsp;&nbsp;&nbsp; &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror(&quot;write error:&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;
&nbsp;&nbsp;&nbsp;&nbsp; &#125;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;gettimeofday(&amp;end, NULL);
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;close(fd);
&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;&#92;&#92;nnoAio second : %d microSec : %d&#92;&#92;n&quot;, end.tv_sec-start.tv_sec, end.tv_usec-start.tv_usec);
&#125;
int main()
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;test();
&nbsp;&nbsp;&nbsp;&nbsp;testAIO();
&nbsp;&nbsp;&nbsp;&nbsp;return 1;
&#125;
</textarea><br/><br/>来源：http://5itest.net/bbs/TopicOther.asp?t=5&amp;BoardID=16&amp;id=1014
]]>
</description>
</item><item>
<link>http://www.jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] [Nginx上传]对Nginx上传进行代码跟踪时对glibc的 Asynchronous I/O 写性能测试这nginx上传模块研究使用。]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>