﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-socketref,再见！高德-随笔分类-gevent</title><link>http://www.cppblog.com/socketref/category/20527.html</link><description>gis,mouse,luolasi</description><language>zh-cn</language><lastBuildDate>Sun, 04 May 2014 09:53:03 GMT</lastBuildDate><pubDate>Sun, 04 May 2014 09:53:03 GMT</pubDate><ttl>60</ttl><item><title>tkInter如何与gevent协作</title><link>http://www.cppblog.com/socketref/archive/2014/05/04/206815.html</link><dc:creator>放屁阿狗 </dc:creator><author>放屁阿狗 </author><pubDate>Sun, 04 May 2014 08:59:00 GMT</pubDate><guid>http://www.cppblog.com/socketref/archive/2014/05/04/206815.html</guid><wfw:comment>http://www.cppblog.com/socketref/comments/206815.html</wfw:comment><comments>http://www.cppblog.com/socketref/archive/2014/05/04/206815.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/socketref/comments/commentRss/206815.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/socketref/services/trackbacks/206815.html</trackback:ping><description><![CDATA[tkinter工作在主线程，而gevent是单线程工作，如何整合在一起？<br />瞅到一段代码，迅速收藏<br /><br /><br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;gevent<br /><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #0000FF; ">from</span>&nbsp;gevent&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;socket<br /><span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;Tkinter&nbsp;as&nbsp;tk<br /><span style="color: #008080; ">&nbsp;4</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;SockLoop(object):<br /><span style="color: #008080; ">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__init__</span>(self,&nbsp;callback):<br /><span style="color: #008080; ">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.callback&nbsp;=&nbsp;callback<br /><span style="color: #008080; ">&nbsp;8</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__call__</span>(self,&nbsp;sock,&nbsp;client):<br /><span style="color: #008080; ">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;1:<br /><span style="color: #008080; ">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mes&nbsp;=&nbsp;sock.recv(256)<br /><span style="color: #008080; ">12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;=&nbsp;self.callback(client,&nbsp;mes)<br /><span style="color: #008080; ">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;ret&nbsp;<span style="color: #0000FF; ">is</span>&nbsp;<span style="color: #0000FF; ">not</span>&nbsp;None:<br /><span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sock.send(ret)<br /><span style="color: #008080; ">15</span>&nbsp;<br /><span style="color: #008080; ">16</span>&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;socket_server(port,&nbsp;callback):<br /><span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ssock&nbsp;=&nbsp;socket.socket(socket.AF_INET,&nbsp;socket.SOCK_STREAM,&nbsp;socket.IPPROTO_TCP)<br /><span style="color: #008080; ">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ssock.setsockopt(socket.SOL_SOCKET,&nbsp;socket.SO_REUSEADDR,&nbsp;1)<br /><span style="color: #008080; ">19</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ssock.bind((<span style="color: #800000; ">''</span>,&nbsp;port))<br /><span style="color: #008080; ">20</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ssock.listen(5)<br /><span style="color: #008080; ">21</span>&nbsp;<br /><span style="color: #008080; ">22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;1:<br /><span style="color: #008080; ">23</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sock,&nbsp;client&nbsp;=&nbsp;ssock.accept()<br /><span style="color: #008080; ">24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gevent.spawn(callback,&nbsp;sock,&nbsp;client)<br /><span style="color: #008080; ">25</span>&nbsp;<br /><span style="color: #008080; ">26</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;App(object):<br /><span style="color: #008080; ">27</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__init__</span>(self,&nbsp;root):<br /><span style="color: #008080; ">28</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.greenlet&nbsp;=&nbsp;None<br /><span style="color: #008080; ">29</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.root&nbsp;=&nbsp;root<br /><span style="color: #008080; ">30</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._build_window(root)<br /><span style="color: #008080; ">31</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.root.after(100,&nbsp;self._connect)<br /><span style="color: #008080; ">32</span>&nbsp;<br /><span style="color: #008080; ">33</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;add_text(self,&nbsp;text):<br /><span style="color: #008080; ">34</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cleaned_string&nbsp;=&nbsp;text.replace(<span style="color: #800000; ">'</span><span style="color: #800000; ">\r</span><span style="color: #800000; ">'</span>,&nbsp;<span style="color: #800000; ">''</span>)<br /><span style="color: #008080; ">35</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.text.insert(tk.END,&nbsp;cleaned_string)<br /><span style="color: #008080; ">36</span>&nbsp;<br /><span style="color: #008080; ">37</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;quit(self):<br /><span style="color: #008080; ">38</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.root.quit()<br /><span style="color: #008080; ">39</span>&nbsp;<br /><span style="color: #008080; ">40</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;_build_window(self,&nbsp;root):<br /><span style="color: #008080; ">41</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.frame&nbsp;=&nbsp;tk.Frame(root)<br /><span style="color: #008080; ">42</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.text&nbsp;=&nbsp;tk.Text(self.frame)<br /><span style="color: #008080; ">43</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.quit_button&nbsp;=&nbsp;tk.Button(self.frame,&nbsp;text=<span style="color: #800000; ">"</span><span style="color: #800000; ">Quit</span><span style="color: #800000; ">"</span>,&nbsp;command=self.quit)<br /><span style="color: #008080; ">44</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.text.pack()<br /><span style="color: #008080; ">45</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.quit_button.pack()<br /><span style="color: #008080; ">46</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.frame.pack()<br /><span style="color: #008080; ">47</span>&nbsp;<br /><span style="color: #008080; ">48</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;_connect(self):<br /><span style="color: #008080; ">49</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.greenlet&nbsp;=&nbsp;gevent.spawn(<br /><span style="color: #008080; ">50</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;socket_server,<br /><span style="color: #008080; ">51</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8080,<br /><span style="color: #008080; ">52</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SockLoop(<span style="color: #0000FF; ">lambda</span>&nbsp;cl,&nbsp;txt:&nbsp;self.add_text(<span style="color: #800000; ">"</span><span style="color: #800000; ">%s:&nbsp;%s</span><span style="color: #800000; ">"</span>&nbsp;%&nbsp;(cl,&nbsp;txt))))<br /><span style="color: #008080; ">53</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.gevent_loop_step()<br /><span style="color: #008080; ">54</span>&nbsp;<br /><span style="color: #008080; ">55</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;gevent_loop_step(self):<br /><span style="color: #008080; ">56</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gevent.sleep()<br /><span style="color: #008080; ">57</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.root.after_idle(self.gevent_loop_step)<br /><span style="color: #008080; ">58</span>&nbsp;<br /><span style="color: #008080; ">59</span>&nbsp;<br /><span style="color: #008080; ">60</span>&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;<span style="color: #800080; ">__name__</span>&nbsp;==&nbsp;<span style="color: #800000; ">'</span><span style="color: #800000; ">__main__</span><span style="color: #800000; ">'</span>:<br /><span style="color: #008080; ">61</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root&nbsp;=&nbsp;tk.Tk()<br /><span style="color: #008080; ">62</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;app&nbsp;=&nbsp;App(root)<br /><span style="color: #008080; ">63</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root.mainloop()</div><img src ="http://www.cppblog.com/socketref/aggbug/206815.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/socketref/" target="_blank">放屁阿狗 </a> 2014-05-04 16:59 <a href="http://www.cppblog.com/socketref/archive/2014/05/04/206815.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>nginx+gevent+webpy+gridfs 提供文件服务集群方案</title><link>http://www.cppblog.com/socketref/archive/2014/03/29/206396.html</link><dc:creator>放屁阿狗 </dc:creator><author>放屁阿狗 </author><pubDate>Sat, 29 Mar 2014 13:27:00 GMT</pubDate><guid>http://www.cppblog.com/socketref/archive/2014/03/29/206396.html</guid><wfw:comment>http://www.cppblog.com/socketref/comments/206396.html</wfw:comment><comments>http://www.cppblog.com/socketref/archive/2014/03/29/206396.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/socketref/comments/commentRss/206396.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/socketref/services/trackbacks/206396.html</trackback:ping><description><![CDATA[系统中，用户的消息在移动设备与接入服务器建立的Tcp长连接上传递。这些消息包括：文本，复合文本，位置信息，音频剪辑，图像等等。<br />发送者传送消息到平台系统内部并将消息写入gridfs，待接收者上线时平台将消息推送至接收者。 <br />考虑到带宽利用，接收者得到的消息将不包含二进制数据，例如: 音频，图像等等。 这要求接收者对平台发起一次获取消息包内指定的音频和图像数据的请求。<br />移动端向平台请求二进制数据的情况还包含 【离线文件传送】场景 。 <br />二进制数据往往是指那些数据量比较大的对象，这些对象在移动两端交换时，交互通道将不占用与接入服务器的连接通道，而是通过nginx传送到平台内部； 同样接收者获取二进制数据也是通过nginx获取。这种请求是HTTP的。<br />这里整理的是如何在平台部署 【负载均衡的集群的分布式的文件服务】<br /><br />nginx :&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http服务，提供反向代理和负载均衡服务（集群可用DNS或考虑LVS方案）<br />mongodb+gridfs : 用于文件服务提供，其内置gridfs提供了分布式，海量存储的方案<br />gevent+webpy : nginx直接读取gridfs是不合适的，配置了cgi才能完成特定功能，这里使用webpy，比django更轻更好用。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; webpy的作用是接收到上传和下传文件的请求，读写gridfs文件内容给移动端。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gevent是高效的通信框架，虽然单线程工作，但性能非常的好；<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用好gevent关键在与外部的io必须全部都是异步的，例如： 数据库，文件磁盘访问等等。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mongodb对gevent已经支持，gevent对webpy，django，psycopg2支持也相当的好，所以要提供webservice服务那就考虑用gevent+webpy或django把，性能是杠杠的，比 apache+mod_wsgi要好很多 ，而且gevent是进程内的不同的HTTP REQUEST可以是共享数据的，这一点非常诱惑(apache+mod_wsgi的REQUEST可是隔离的哦！除非您通过redis的PUB/SUB实现两个REQUEST的通信)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />关注的问题：<br />１.下传大文件时的处理<br />　　　如果直接用nginx当然没有这个问题　，但用webpy读取文件返回HttpResponse时问题来了，总不至于读取整个文件，然后再return。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这种方式在php有flush方法，python只能用yield来做<br />&nbsp;2.上传大文件时的处理<br />&nbsp; &nbsp; &nbsp; &nbsp; 当接收到http的文件POST请求时，文件已经全部缓存到web服务器，如果同时几千个文件上传在进行，服务器就会被挤爆，这也是很多网站不允许大文件上传的缘故吧。关于这个问题，我想就需要修改一下webpy关于文件上传的处理代码了，将接收到的文件数据以流的形式写入到gridfs里去作为临时文件被缓存，等完全接收文件时，才通知到handler代码，这样必定高效很多(新的问题又来了，会不会把gridfs搞爆掉! 处理时考虑延时缓存提交gridfs把)。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">BUF_SIZE&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">262144</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;download:<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">def</span><span style="color: #000000; ">&nbsp;GET(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file_name&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #800000; ">'</span><span style="color: #800000; ">file_name</span><span style="color: #800000; ">'</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file_path&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;os.path.join(</span><span style="color: #800000; ">'</span><span style="color: #800000; ">file_path</span><span style="color: #800000; ">'</span><span style="color: #000000; ">,&nbsp;file_name)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;None<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">try</span><span style="color: #000000; ">:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;open(file_path,&nbsp;</span><span style="color: #800000; ">"</span><span style="color: #800000; ">rb</span><span style="color: #800000; ">"</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;webpy.header(</span><span style="color: #800000; ">'</span><span style="color: #800000; ">Content-Type</span><span style="color: #800000; ">'</span><span style="color: #000000; ">,</span><span style="color: #800000; ">'</span><span style="color: #800000; ">application/octet-stream</span><span style="color: #800000; ">'</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;webpy.header(</span><span style="color: #800000; ">'</span><span style="color: #800000;">Content-disposition</span><span style="color: #800000; ">'</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #800000; ">'</span><span style="color: #800000; ">attachment;&nbsp;filename=%s.dat</span><span style="color: #800000; ">'</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">%</span><span style="color: #000000; ">&nbsp;file_name)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">&nbsp;True:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;f.read(BUF_SIZE)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;c:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">yield</span><span style="color: #000000; ">&nbsp;c<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; ">:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">break</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">except</span><span style="color: #000000; ">&nbsp;Exception,&nbsp;e:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">print</span><span style="color: #000000; ">&nbsp;e<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">yield</span><span style="color: #000000; ">&nbsp;</span><span style="color: #800000; ">'</span><span style="color: #800000; ">Error</span><span style="color: #800000; ">'</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">finally</span><span style="color: #000000; ">:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;f:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.close()<br /></span></div><br /><br /><br />links: <br /><div>http://api.mongodb.org/python</div><div>http://webpy.org/cookbook/storeupload.zh-cn</div><div>http://webpy.org/cookbook/streaming_large_files</div>http://gevent.org&nbsp;&nbsp; 下份代码 demo很值得看哦 gevent 1.0 由libev 替换了libevent<br /><br />　<br /><img src ="http://www.cppblog.com/socketref/aggbug/206396.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/socketref/" target="_blank">放屁阿狗 </a> 2014-03-29 21:27 <a href="http://www.cppblog.com/socketref/archive/2014/03/29/206396.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>gevent数据库连接测试</title><link>http://www.cppblog.com/socketref/archive/2013/09/25/203423.html</link><dc:creator>放屁阿狗 </dc:creator><author>放屁阿狗 </author><pubDate>Tue, 24 Sep 2013 18:08:00 GMT</pubDate><guid>http://www.cppblog.com/socketref/archive/2013/09/25/203423.html</guid><wfw:comment>http://www.cppblog.com/socketref/comments/203423.html</wfw:comment><comments>http://www.cppblog.com/socketref/archive/2013/09/25/203423.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/socketref/comments/commentRss/203423.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/socketref/services/trackbacks/203423.html</trackback:ping><description><![CDATA[<br />同样在函数中连接pgsql，然后执行500次查询，<br />测试gevent模式、串行查询、多线程查询 <br />数据如下：&nbsp;<br /><div>multithread_test cost time: 2.45199990273</div><div>normal_test cost time: 4.04299998283</div><div>gevent_test cost time: 2.12800002098</div>结果 串行最慢4.4s, 多线程 2.45s ,gevent最快2.12 ,yes!<br /><br />测试代码:&nbsp;<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;gevent<br /><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;gevent.queue<br /><span style="color: #008080; ">&nbsp;3</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;psycopg2<br /><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;psycopg2.extensions<br /><span style="color: #008080; ">&nbsp;6</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;psycogreen.gevent<br /><span style="color: #008080; ">&nbsp;8</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;9</span>&nbsp;psycogreen.gevent.patch_psycopg()<br /><span style="color: #008080; ">10</span>&nbsp;<br /><span style="color: #008080; ">11</span>&nbsp;sys.path.insert(0,<span style="color: #800000; ">'</span><span style="color: #800000; ">../</span><span style="color: #800000; ">'</span>)<br /><span style="color: #008080; ">12</span>&nbsp;<br /><span style="color: #008080; ">13</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;easymq<br /><span style="color: #008080; ">14</span>&nbsp;<br /><span style="color: #008080; ">15</span>&nbsp;<span style="color: #800000; ">'''</span><span style="color: #800000; "><br /></span><span style="color: #008080; ">16</span>&nbsp;<span style="color: #800000; ">在同一线程中，同一个连接conn上两次创建的cur将会是一样滴，因为是异步wait_read()缘故<br /></span><span style="color: #008080; ">17</span>&nbsp;<span style="color: #800000; ">所以要么每次创建数据库连接，要么使用dbpool<br /></span><span style="color: #008080; ">18</span>&nbsp;<span style="color: #800000; "></span><span style="color: #800000; ">'''</span><br /><span style="color: #008080; ">19</span>&nbsp;<br /><span style="color: #008080; ">20</span>&nbsp;<br /><span style="color: #008080; ">21</span>&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;readThread():<br /><span style="color: #008080; ">22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn&nbsp;=&nbsp;psycopg2.connect(database=<span style="color: #800000; ">'</span><span style="color: #800000; ">postgres</span><span style="color: #800000; ">'</span>,user=<span style="color: #800000; ">'</span><span style="color: #800000; ">postgres</span><span style="color: #800000; ">'</span>,password=<span style="color: #800000; ">'</span><span style="color: #800000; ">111111</span><span style="color: #800000; ">'</span>)<br /><span style="color: #008080; ">23</span>&nbsp;<br /><span style="color: #008080; ">24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;cur&nbsp;=&nbsp;conn.cursor(cursor_factory=psycopg2.extensions.DictCursor)</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">25</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;cur&nbsp;=&nbsp;conn.cursor(cursor_factory=psycopg2.extensions.cursor)<br /><span style="color: #008080; ">26</span>&nbsp;<br /><span style="color: #008080; ">27</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;cur.execute("select&nbsp;pg_sleep(%s)",&nbsp;(2,))</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">28</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;n&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;range(10):<br /><span style="color: #008080; ">29</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cur.execute(<span style="color: #800000; ">"</span><span style="color: #800000; ">select&nbsp;CURRENT_DATE</span><span style="color: #800000; ">"</span>)<br /><span style="color: #008080; ">30</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;print&nbsp;cur.fetchone()</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">31</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;print&nbsp;'read&nbsp;end..'</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">32</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;conn&nbsp;=&nbsp;None<br /><span style="color: #008080; ">33</span>&nbsp;<br /><span style="color: #008080; ">34</span>&nbsp;<br /><span style="color: #008080; ">35</span>&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;gevent_test():<br /><span style="color: #008080; ">36</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jobs=[]<br /><span style="color: #008080; ">37</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;n&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;range(100):<br /><span style="color: #008080; ">38</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jobs.append(gevent.spawn(readThread))<br /><span style="color: #008080; ">39</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gevent.joinall(jobs)<br /><span style="color: #008080; ">40</span>&nbsp;<br /><span style="color: #008080; ">41</span>&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;normal_test():<br /><span style="color: #008080; ">42</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;n&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;range(100):<br /><span style="color: #008080; ">43</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readThread()<br /><span style="color: #008080; ">44</span>&nbsp;<br /><span style="color: #008080; ">45</span>&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;multithread_test():<br /><span style="color: #008080; ">46</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threads=[]<br /><span style="color: #008080; ">47</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;n&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;range(100):<br /><span style="color: #008080; ">48</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thread&nbsp;=&nbsp;threading.Thread(target=readThread)<br /><span style="color: #008080; ">49</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threads.append(thread)<br /><span style="color: #008080; ">50</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thread.start()<br /><span style="color: #008080; ">51</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;thread&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;threads:<br /><span style="color: #008080; ">52</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thread.join()<br /><span style="color: #008080; ">53</span>&nbsp;<br /><span style="color: #008080; ">54</span>&nbsp;start&nbsp;=&nbsp;time.time()<br /><span style="color: #008080; ">55</span>&nbsp;normal_test()<br /><span style="color: #008080; ">56</span>&nbsp;end&nbsp;=&nbsp;time.time()<br /><span style="color: #008080; ">57</span>&nbsp;<span style="color: #0000FF; ">print</span>&nbsp;<span style="color: #800000; ">'</span><span style="color: #800000; ">normal_test&nbsp;cost&nbsp;time:</span><span style="color: #800000; ">'</span>,end-start<br /><span style="color: #008080; ">58</span>&nbsp;<br /><span style="color: #008080; ">59</span>&nbsp;start&nbsp;=&nbsp;time.time()<br /><span style="color: #008080; ">60</span>&nbsp;gevent_test()<br /><span style="color: #008080; ">61</span>&nbsp;end&nbsp;=&nbsp;time.time()<br /><span style="color: #008080; ">62</span>&nbsp;<span style="color: #0000FF; ">print</span>&nbsp;<span style="color: #800000; ">'</span><span style="color: #800000; ">gevent_test&nbsp;cost&nbsp;time:</span><span style="color: #800000; ">'</span>,end-start<br /><span style="color: #008080; ">63</span>&nbsp;<br /><span style="color: #008080; ">64</span>&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;start&nbsp;=&nbsp;time.time()</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">65</span>&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;multithread_test()</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">66</span>&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;end&nbsp;=&nbsp;time.time()</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">67</span>&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;print&nbsp;'multithread_test&nbsp;cost&nbsp;time:',end-start</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">68</span>&nbsp;<span style="color: #008000; "></span></div><img src ="http://www.cppblog.com/socketref/aggbug/203423.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/socketref/" target="_blank">放屁阿狗 </a> 2013-09-25 02:08 <a href="http://www.cppblog.com/socketref/archive/2013/09/25/203423.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我的平台框架</title><link>http://www.cppblog.com/socketref/archive/2013/09/25/203422.html</link><dc:creator>放屁阿狗 </dc:creator><author>放屁阿狗 </author><pubDate>Tue, 24 Sep 2013 16:35:00 GMT</pubDate><guid>http://www.cppblog.com/socketref/archive/2013/09/25/203422.html</guid><wfw:comment>http://www.cppblog.com/socketref/comments/203422.html</wfw:comment><comments>http://www.cppblog.com/socketref/archive/2013/09/25/203422.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/socketref/comments/commentRss/203422.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/socketref/services/trackbacks/203422.html</trackback:ping><description><![CDATA[<br />搞了这么久的RPC通信框架TCE，完成java，c++,python,javascript,actionscript之间的互相调来调去，感觉很舒服。<br /><br />作为移动应用平台，海量并发和高效传输是首要考虑要点。<br />市面上充值着都差不多的解决技术方案，无非那些 <br />webserver+db<br />ngnix+webserver+mq+logic-server<br />ngnix+gevent-wsgi+db<br />webapi已经被高举到不可超越的地步<br /><br />而我，不走寻常路，我得另辟捷径<br />-http的效率根本无法跟socket的长连接媲美<br />-服务器是需要反向推送消息到移动设备的<br />-操作接口是简单的易扩展的，屏蔽掉通信细节<br />-支持htm5的websocket，支持java，支持python，支持python客户端调用<br /><br />那我的方案是tce为基础的RPC框架平台，抛弃那些xmls，json，让开发者从无尽的网络编解码工作中脱离出来，不用考虑多种通信模式，同步和异步。<br />font-gate : &nbsp;前端接入服务器<br />easymq &nbsp;: 平台服务总线消息队列&nbsp;<br />logic-service ： 不同的逻辑服务器<br /><br />设想，在android手机上java代码调用函数 whats_yourname(), 这个函数并不在本地，而是存在远端平台内部的一个服务器上,调用并被执行返回'scott'到手机终端，这是多么令人快乐的事情，用户不用关心消息如何被列集，如何被分派，这一切都是透明的。<br />同样，服务器主动推送商品打折信息到手机上，服务器仅仅需要调用手机接收函数，并填写要传输的参数即可。<br />其实，这些就是RPC的实现，这样的东东到处都是,DCOM，CORBA，ICE，只是我做得更加灵活<br /><br />总是想做些令人轻松并快乐的事情！<br /><img src ="http://www.cppblog.com/socketref/aggbug/203422.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/socketref/" target="_blank">放屁阿狗 </a> 2013-09-25 00:35 <a href="http://www.cppblog.com/socketref/archive/2013/09/25/203422.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>gevent整合第三方软件包需注意问题</title><link>http://www.cppblog.com/socketref/archive/2013/09/24/203421.html</link><dc:creator>放屁阿狗 </dc:creator><author>放屁阿狗 </author><pubDate>Tue, 24 Sep 2013 15:47:00 GMT</pubDate><guid>http://www.cppblog.com/socketref/archive/2013/09/24/203421.html</guid><wfw:comment>http://www.cppblog.com/socketref/comments/203421.html</wfw:comment><comments>http://www.cppblog.com/socketref/archive/2013/09/24/203421.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/socketref/comments/commentRss/203421.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/socketref/services/trackbacks/203421.html</trackback:ping><description><![CDATA[gevent作为一款优秀的网络通信框架，其出色的性能得到大家一致认可，但在处理并行任务的时候也要注意很多问题，不然您的服务器将变得异常缓慢。<br /><div><a href="http://blog.163.com/lxl_1995/blog/static/677173392012724103742746/" style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">http://blog.163.com/lxl_1995/blog/static/677173392012724103742746/<br />这篇</a>博文讲的非常清楚，建议读一下&nbsp;<br /><br />gevent的特点如下：&nbsp;<br />&nbsp;1. 单线程执行，所有协程都在同一进程中被模拟和调度分派<br />&nbsp;2. 可以创建成千上万的 协程，而不会受任何性能影响<br />3. 由于spawn的协程不是os分配和管理，所以不会有额外的线程资源分配，cpu也不用在这些线程之间调度切换<br />4. 单线程执行，无需考虑资源互斥<br />5. 协程之间切换是通过gevent的io阻塞完成，例如 gevent.sleep(0), queue.get/put,event,socket....<br />&nbsp; &nbsp; 每调用一次gevent 的api，gevent就能获得一次schedule的机会(这很类似操作系统的用户调用中断，由用户态切换到内核态)<br /><br />&nbsp;以上特点保证gevent的性能非常出色，但当我们的server用到第三方软件包的时候那要非常小心了，特别是这些包内部涉及了io操作。<br />如果第三方软件包是纯python的那很简单，只需要gevent.monkey_patch(xxx)就okay； 但如果包是扩展clib,那要当心了，monkey_patch<br />并不能将其相关io操作打上补丁，为了使用这些第三方软件包，要求这些软件包必须支持 协程异步 接口(调用其同步io接口，将阻塞住gevent的执行线程，那gevent就完蛋了)。<br />gevent的patch对psycopg2无效，因为psycopg2的通信部分是c接口的函数库，还好psycopg2内部支持协程，需要使用 到&nbsp;<a href="http://bitbucket.org/dvarrazzo/psycogreen/" rel="nofollow" style="color: #0000cc; font-family: arial, sans-serif; font-size: 13px; line-height: normal; background-color: #ffffff;">psycogreen</a>&nbsp;这个东东</div><span style="color: #333333; font-family: monospace; font-size: 13px; font-weight: bold; line-height: 18px; background-color: #f5f5f5;">psycogreen.gevent.patch_psycopg() 支持协程<br /></span>之后的在gevent的线程中执行sql并等待数据返回时，gevent立马将执行切换到另外的线程<br /><br />gvent项目中会用到各种诸多的第三方库，必须要求这些库的io接口不能是阻塞的，也就是能支持到gevent异步模式<br /><br />应用逻辑代码在被执行时(无系统api呼叫)，单线程比多线程执行速度更快。循环执行一段计算二次函数代码，由于期间没有系统api调用，os不能进行内核tasklet切换，所以导致cpu的峰值可以攀升到90%，直到硬件、时钟等中断产生，强行切换到其他线程。 多核心cpu表现为单个核始终异常的忙碌，其他几个比较空闲。&nbsp;<br /><img src ="http://www.cppblog.com/socketref/aggbug/203421.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/socketref/" target="_blank">放屁阿狗 </a> 2013-09-24 23:47 <a href="http://www.cppblog.com/socketref/archive/2013/09/24/203421.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>gevent之Queue</title><link>http://www.cppblog.com/socketref/archive/2013/09/19/203306.html</link><dc:creator>放屁阿狗 </dc:creator><author>放屁阿狗 </author><pubDate>Thu, 19 Sep 2013 06:44:00 GMT</pubDate><guid>http://www.cppblog.com/socketref/archive/2013/09/19/203306.html</guid><wfw:comment>http://www.cppblog.com/socketref/comments/203306.html</wfw:comment><comments>http://www.cppblog.com/socketref/archive/2013/09/19/203306.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/socketref/comments/commentRss/203306.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/socketref/services/trackbacks/203306.html</trackback:ping><description><![CDATA[Queue用于生产者、消费者模型&nbsp;<br />gevent提供了'Queue', 'PriorityQueue', 'LifoQueue', 'JoinableQueue' 四种队列，文档介绍不全 ，看了代码方才了解<br /><br />所有队列类型都是安全的(synchronized queue) ,数据推入和提取无需访问保护<br /><br />LifoQueue - 后进先出队列，同数据堆栈结构<br />JoinableQueue - &nbsp;增加join，所有数据提取完毕join解除阻塞&nbsp;<br />PriorityQueue - 优先级队列，提取根据置入时的优先级别<br />Queue - 超类消息队列，提供同步数据置入和提取功能，其他队列均从Queue派生<img src ="http://www.cppblog.com/socketref/aggbug/203306.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/socketref/" target="_blank">放屁阿狗 </a> 2013-09-19 14:44 <a href="http://www.cppblog.com/socketref/archive/2013/09/19/203306.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>gevent::AsyncResult</title><link>http://www.cppblog.com/socketref/archive/2013/05/14/200238.html</link><dc:creator>放屁阿狗 </dc:creator><author>放屁阿狗 </author><pubDate>Mon, 13 May 2013 17:04:00 GMT</pubDate><guid>http://www.cppblog.com/socketref/archive/2013/05/14/200238.html</guid><wfw:comment>http://www.cppblog.com/socketref/comments/200238.html</wfw:comment><comments>http://www.cppblog.com/socketref/archive/2013/05/14/200238.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/socketref/comments/commentRss/200238.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/socketref/services/trackbacks/200238.html</trackback:ping><description><![CDATA[看到 AsyncResult这个类，想到我之前自己写的处理异步返回值的类&nbsp;<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;MutexObject:<br /><span style="color: #008080; ">&nbsp;2</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__init__</span>(self):<br /><span style="color: #008080; ">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.mtx&nbsp;=&nbsp;threading.Condition()<br /><span style="color: #008080; ">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.d&nbsp;=&nbsp;None<br /><span style="color: #008080; ">&nbsp;5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="color: #008080; ">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;waitObject(self,timeout):<br /><span style="color: #008080; ">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d&nbsp;=&nbsp;None<br /><span style="color: #008080; ">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.mtx.acquire()<br /><span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;self.d&nbsp;==&nbsp;None:<br /><span style="color: #008080; ">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;timeout:<br /><span style="color: #008080; ">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.mtx.wait(timeout)<br /><span style="color: #008080; ">12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span>:<br /><span style="color: #008080; ">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.mtx.wait()<br /><span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d&nbsp;=&nbsp;self.d<br /><span style="color: #008080; ">15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.d&nbsp;=&nbsp;None<br /><span style="color: #008080; ">16</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.mtx.release()<br /><span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;d<br /><span style="color: #008080; ">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="color: #008080; ">19</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;notify(self,d):<br /><span style="color: #008080; ">20</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.mtx.acquire()<br /><span style="color: #008080; ">21</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.d&nbsp;=&nbsp;d<br /><span style="color: #008080; ">22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.mtx.notify()<br /><span style="color: #008080; ">23</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.mtx.release()</div><img src ="http://www.cppblog.com/socketref/aggbug/200238.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/socketref/" target="_blank">放屁阿狗 </a> 2013-05-14 01:04 <a href="http://www.cppblog.com/socketref/archive/2013/05/14/200238.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>