<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_智慧 + 毅力 = 无所不能</title><subtitle type="text">正确性、健壮性、可靠性、效率、易用性、可读性、可复用性、兼容性、可移植性...</subtitle><id>http://feed.cnblogs.com/blog/u/60107/rss</id><updated>2011-09-13T07:44:43Z</updated><author><name>Seven_Yuan</name><uri>http://www.cnblogs.com/sevenyuan/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/sevenyuan/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/60107/rss"/><entry><id>http://www.cnblogs.com/sevenyuan/archive/2011/09/13/2174800.html</id><title type="text">3D图形学算法</title><summary type="text">http://blog.csdn.net/popy007</summary><published>2011-09-13T07:45:00Z</published><updated>2011-09-13T07:45:00Z</updated><author><name>Seven_Yuan</name><uri>http://www.cnblogs.com/sevenyuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/sevenyuan/archive/2011/09/13/2174800.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/sevenyuan/archive/2011/09/13/2174800.html"/><content type="html">&lt;p&gt;&lt;a href="http://blog.csdn.net/popy007"&gt;http://blog.csdn.net/popy007&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/sevenyuan/aggbug/2174800.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/sevenyuan/archive/2011/09/13/2174800.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/sevenyuan/archive/2010/12/20/1911670.html</id><title type="text">线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法</title><summary type="text">转自：http://www.itcodeworld.com/?p=105使用结构CRITICAL_SECTION 需加入头文件#include “afxmt.h”定义一个全局的锁 CRITICAL_SECTION的实例和一个静态全局变量[代码]创建两个线程函数，代码实现如下：代码在主函数添加以下代码代码输出：n_AddValue in FirstThread is 1n_AddValue in FirstThread is 2n_AddValue in FirstThread is 3n_AddValue in FirstThread is 4n_AddValue in FirstThread</summary><published>2010-12-20T09:45:00Z</published><updated>2010-12-20T09:45:00Z</updated><author><name>Seven_Yuan</name><uri>http://www.cnblogs.com/sevenyuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/20/1911670.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/20/1911670.html"/><content type="html">&lt;p&gt;转自：http://www.itcodeworld.com/?p=105&lt;/p&gt;&#xD;
&lt;p&gt;使用结构CRITICAL_SECTION 需加入头文件#include &amp;ldquo;afxmt.h&amp;rdquo;&lt;/p&gt;&#xD;
&lt;p&gt;定义一个全局的锁 CRITICAL_SECTION的实例&lt;br /&gt;和一个静态全局变量&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #000000;"&gt;CRITICAL_SECTION cs;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;可以理解为锁定一个资源&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; n_AddValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;定义一个静态的全部变量n_AddValue&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;创建两个线程函数，代码实现如下：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('01280526-aed8-4c3d-bade-720d699f29b4')"&gt;&#xD;
&lt;div id="cnblogs_code_open_01280526-aed8-4c3d-bade-720d699f29b4"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;第一个线程&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;UINT FirstThread(LPVOID lParam)&lt;br /&gt;{&lt;br /&gt;     EnterCriticalSection(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;cs);&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;加锁 接下来的代码处理过程中不允许其他线程进行操作，除非遇到LeaveCriticalSection&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;     &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;){       &lt;br /&gt;         n_AddValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;         cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;n_AddValue in FirstThread is &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;n_AddValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;endl;       &lt;br /&gt;     }&lt;br /&gt;     LeaveCriticalSection(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;cs);&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;解锁 到EnterCriticalSection之间代码资源已经释放了，其他线程可以进行操作   &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;     &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;第二个线程&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;UINT SecondThread(LPVOID lParam)&lt;br /&gt;{&lt;br /&gt;    EnterCriticalSection(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;cs);&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;加锁&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;){       &lt;br /&gt;        n_AddValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;;       &lt;br /&gt;        cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;n_AddValue in SecondThread is &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;n_AddValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;endl;   &lt;br /&gt;       &lt;br /&gt;    }&lt;br /&gt;    LeaveCriticalSection(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;cs);&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;解锁&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在主函数添加以下代码&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('8ef9b9b9-f10b-4dd5-ab81-7532eebe9837')"&gt;&#xD;
&lt;div id="cnblogs_code_open_8ef9b9b9-f10b-4dd5-ab81-7532eebe9837"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; _tmain(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; argc, TCHAR&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; argv[], TCHAR&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; envp[])&lt;br /&gt; {&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; nRetCode &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt; &lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 初始化 MFC 并在失败时显示错误&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;     &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;))&lt;br /&gt;    {&lt;br /&gt;         &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; TODO: 更改错误代码以符合您的需要&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;         _tprintf(_T(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;错误: MFC 初始化失败\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;));&lt;br /&gt;        nRetCode &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;     }&lt;br /&gt;     &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;    {&lt;br /&gt;        InitializeCriticalSection(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;cs);&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;初始化结构CRITICAL_SECTION&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;        CWinThread &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;pFirstThread,&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;pSecondThread;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;存储函数AfxBeginThread返回的CWinThread指针&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;       &lt;br /&gt;        pFirstThread  &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; AfxBeginThread(FirstThread,LPVOID(NULL));&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;启动第一个线程&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        pSecondThread &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; AfxBeginThread(SecondThread,LPVOID(NULL));&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;启动第二个线程&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;  &lt;br /&gt;        HANDLE hThreadHandle[&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;];&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        hThreadHandle[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pFirstThread&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;m_hThread;&lt;br /&gt;        hThreadHandle[&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pSecondThread&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;m_hThread;&lt;br /&gt; &lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;等待线程返回&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        WaitForMultipleObjects(&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;,hThreadHandle,TRUE,INFINITE);       &lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; nRetCode;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;输出：&lt;/p&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;p&gt;n_AddValue in FirstThread is 1&lt;br /&gt;n_AddValue in FirstThread is 2&lt;br /&gt;n_AddValue in FirstThread is 3&lt;br /&gt;n_AddValue in FirstThread is 4&lt;br /&gt;n_AddValue in FirstThread is 5&lt;br /&gt;n_AddValue in FirstThread is 6&lt;br /&gt;n_AddValue in FirstThread is 7&lt;br /&gt;n_AddValue in FirstThread is 8&lt;br /&gt;n_AddValue in FirstThread is 9&lt;br /&gt;n_AddValue in FirstThread is 10&lt;br /&gt;n_AddValue in SecondThread is 11&lt;br /&gt;n_AddValue in SecondThread is 12&lt;br /&gt;n_AddValue in SecondThread is 13&lt;br /&gt;n_AddValue in SecondThread is 14&lt;br /&gt;n_AddValue in SecondThread is 15&lt;br /&gt;n_AddValue in SecondThread is 16&lt;br /&gt;n_AddValue in SecondThread is 17&lt;br /&gt;n_AddValue in SecondThread is 18&lt;br /&gt;n_AddValue in SecondThread is 19&lt;br /&gt;n_AddValue in SecondThread is 20&lt;/p&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;p&gt;如果把两个线程函数中的EnterCriticalSection和LeaveCriticalSection位置移到for循环中去，线程的执行顺序将会改变&lt;br /&gt;输出也就跟着改变，如：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('52b768c9-0672-45ed-ac7e-793514b250c6')"&gt;&#xD;
&lt;div id="cnblogs_code_open_52b768c9-0672-45ed-ac7e-793514b250c6"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;第一个线程&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; UINT FirstThread(LPVOID lParam)&lt;br /&gt;{&lt;br /&gt;    &lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;){&lt;br /&gt;        EnterCriticalSection(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;cs);&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;加锁 锁移到for循环内部里&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        n_AddValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;        cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;n_AddValue in FirstThread is &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;n_AddValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;endl;   &lt;br /&gt;        LeaveCriticalSection(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;cs);&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;解锁 &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    }   &lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;}&lt;br /&gt;  &lt;br /&gt; &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;第二个线程&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;UINT SecondThread(LPVOID lParam)&lt;br /&gt;{&lt;br /&gt;   &lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;){   &lt;br /&gt;        EnterCriticalSection(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;cs);&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;加锁&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        n_AddValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;;       &lt;br /&gt;        cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;n_AddValue in SecondThread is &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;n_AddValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;endl;&lt;br /&gt;        LeaveCriticalSection(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;cs);&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;解锁       &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;     }&lt;br /&gt;     &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt; }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;其他代码不变，输出的结果如下：&lt;/p&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;p&gt;n_AddValue in FirstThread is 1&lt;br /&gt;n_AddValue in SecondThread is 2&lt;br /&gt;n_AddValue in FirstThread is 3&lt;br /&gt;n_AddValue in SecondThread is 4&lt;br /&gt;n_AddValue in FirstThread is 5&lt;br /&gt;n_AddValue in SecondThread is 6&lt;br /&gt;n_AddValue in FirstThread is 7&lt;br /&gt;n_AddValue in SecondThread is 8&lt;br /&gt;n_AddValue in FirstThread is 9&lt;br /&gt;n_AddValue in SecondThread is 10&lt;br /&gt;n_AddValue in FirstThread is 11&lt;br /&gt;n_AddValue in SecondThread is 12&lt;br /&gt;n_AddValue in FirstThread is 13&lt;br /&gt;n_AddValue in SecondThread is 14&lt;br /&gt;n_AddValue in FirstThread is 15&lt;br /&gt;n_AddValue in SecondThread is 16&lt;br /&gt;n_AddValue in FirstThread is 17&lt;br /&gt;n_AddValue in SecondThread is 18&lt;br /&gt;n_AddValue in FirstThread is 19&lt;br /&gt;n_AddValue in SecondThread is 20 &lt;/p&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;p&gt;个人认为在函数EnterCriticalSection和LeaveCriticalSection中间的代码执行过程不会被其他线程干拢或者这么讲不允许其他线程中&lt;br /&gt;的代码执行。这样可以有效防止一个全局变量在两个线程中同时被操作的可能性&lt;/p&gt;&lt;img src="http://www.cnblogs.com/sevenyuan/aggbug/1911670.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/sevenyuan/archive/2010/12/20/1911670.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/sevenyuan/archive/2010/12/15/1907290.html</id><title type="text">C/C++ 宏</title><summary type="text">众多C++书籍都忠告我们C语言宏是万恶之首，但事情总不如我们想象的那么坏，就如同goto一样。宏有一个很大的作用，就是自动为我们产生代码。如果说模板可以为我们产生各种型别的代码(型别替换)，那么宏其实可以为我们在符号上产生新的代码(即符号替换、增加)。关于宏的一些语法问题，可以在google上找到。相信我，你对于宏的了解绝对没你想象的那么多。如果你还不知道#和##，也不知道prescan，那么你肯定对宏的了解不够。我稍微讲解下宏的一些语法问题(说语法问题似乎不妥，macro只与preprocessor有关，跟语义分析又无关)：1. 宏可以像函数一样被定义，例如： #define min(x,y</summary><published>2010-12-15T13:43:00Z</published><updated>2010-12-15T13:43:00Z</updated><author><name>Seven_Yuan</name><uri>http://www.cnblogs.com/sevenyuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/15/1907290.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/15/1907290.html"/><content type="html">&lt;p&gt;众多C++书籍都忠告我们C语言宏是万恶之首，但事情总不如我们想象的那么坏，就如同goto一样。宏有&lt;br /&gt;一个很大的作用，就是自动为我们产生代码。如果说模板可以为我们产生各种型别的代码(&lt;span style="color: #0000ff;"&gt;型别替换&lt;/span&gt;)，&lt;br /&gt;那么宏其实可以为我们&lt;span style="color: #0000ff;"&gt;在符号上&lt;/span&gt;产生新的代码(即符号替换、增加)。&lt;/p&gt;&#xD;
&lt;p&gt;关于宏的一些语法问题，可以在google上找到。相信我，你对于宏的了解绝对没你想象的那么多。如果你&lt;br /&gt;还不知道#和##，也不知道prescan，那么你肯定对宏的了解不够。&lt;/p&gt;&#xD;
&lt;p&gt;我稍微讲解下宏的一些语法问题(说语法问题似乎不妥，macro只与preprocessor有关，跟语义分析又无关)：&lt;/p&gt;&#xD;
&lt;p&gt;1. 宏可以像函数一样被定义，例如：&lt;br /&gt;&amp;nbsp;&amp;nbsp; #define min(x,y) (x&amp;lt;y?x:y) //事实上这个宏存在BUG&lt;br /&gt;&amp;nbsp;&amp;nbsp; 但是在实际使用时，只有当写上min()，必须加括号，min才会被作为宏展开，否则不做任何处理。&lt;br /&gt;2. 如果宏需要参数，你可以不传，编译器会给你警告(宏参数不够)，但是这会导致错误。如C++书籍中所描&lt;br /&gt;&amp;nbsp;&amp;nbsp; 述的，编译器(预处理器)对宏的语法检查不够，所以更多的检查性工作得你自己来做。&lt;/p&gt;&#xD;
&lt;p&gt;3. 很多程序员不知道的#和##&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #0000ff;"&gt;#符号把一个符号直接转换为字符串&lt;/span&gt;，例如：&lt;br /&gt;&amp;nbsp;&amp;nbsp; #define STRING(x) #x&lt;br /&gt;&amp;nbsp;&amp;nbsp; const char *str = STRING( test_string ); str的内容就是"test_string"，也就是说#会把其后的符号&lt;br /&gt;&amp;nbsp;&amp;nbsp; 直接加上双引号。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000ff;"&gt; ##符号会连接两个符号，从而产生新的符号(词法层次)&lt;/span&gt;，例如：&lt;br /&gt;&amp;nbsp;&amp;nbsp; #define SIGN( x ) INT_##x&lt;br /&gt;&amp;nbsp;&amp;nbsp; int SIGN( 1 ); 宏被展开后将成为：int INT_1; &lt;/p&gt;&#xD;
&lt;p&gt;4. 变参宏，这个比较酷，它使得你可以定义类似的宏：&lt;br /&gt;&amp;nbsp;&amp;nbsp; #define LOG( format, ... ) printf( format, __VA_ARGS__ )&lt;br /&gt;&amp;nbsp;&amp;nbsp; LOG( "%s %d", str, count );&lt;br /&gt;&amp;nbsp;&amp;nbsp; __VA_ARGS__是系统预定义宏，被自动替换为参数列表。&lt;/p&gt;&#xD;
&lt;p&gt;5. 当一个宏自己调用自己时，会发生什么？例如：&lt;br /&gt;&amp;nbsp;&amp;nbsp; #define TEST( x ) ( x + TEST( x ) )&lt;br /&gt;&amp;nbsp;&amp;nbsp; TEST( 1 ); 会发生什么？为了防止无限制递归展开，语法规定，当一个宏遇到自己时，就停止展开，也就是&lt;br /&gt;&amp;nbsp;&amp;nbsp; 说，当对TEST( 1 )进行展开时，展开过程中又发现了一个TEST，那么就将这个TEST当作一般的符号。TEST(1)&lt;br /&gt;&amp;nbsp;&amp;nbsp; 最终被展开为：1 + TEST( 1) 。&lt;/p&gt;&#xD;
&lt;p&gt;6. 宏参数的prescan，&lt;br /&gt;&amp;nbsp;&amp;nbsp; 当一个宏参数被放进宏体时，这个宏参数会首先被全部展开(有例外，见下文)。当展开后的宏参数被放进宏体时，&lt;br /&gt;&amp;nbsp;&amp;nbsp; 预处理器对新展开的宏体进行第二次扫描，并继续展开。例如：&lt;br /&gt;&amp;nbsp;&amp;nbsp; #define PARAM( x ) x&lt;br /&gt;&amp;nbsp;&amp;nbsp; #define ADDPARAM( x ) INT_##x&lt;br /&gt;&amp;nbsp;&amp;nbsp; PARAM( ADDPARAM( 1 ) ); &lt;br /&gt;&amp;nbsp;&amp;nbsp; 因为ADDPARAM( 1 ) 是作为PARAM的宏参数，所以先将ADDPARAM( 1 )展开为INT_1，然后再将INT_1放进PARAM。&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp; 例外情况是，如果PARAM宏里对宏参数使用了#或##，那么宏参数不会被展开：&lt;br /&gt;&amp;nbsp;&amp;nbsp; #define PARAM( x ) #x&lt;br /&gt;&amp;nbsp;&amp;nbsp; #define ADDPARAM( x ) INT_##x&lt;br /&gt;&amp;nbsp;&amp;nbsp; PARAM( ADDPARAM( 1 ) ); 将被展开为"ADDPARAM( 1 )"。&lt;/p&gt;&#xD;
&lt;p&gt;使用这么一个规则，可以创建一个很有趣的技术：打印出一个宏被展开后的样子，这样可以方便你分析代码：&lt;br /&gt;&amp;nbsp;&amp;nbsp; #define TO_STRING( x ) TO_STRING1( x )&lt;br /&gt;&amp;nbsp;&amp;nbsp; #define TO_STRING1( x ) #x&lt;br /&gt;&amp;nbsp;&amp;nbsp; TO_STRING首先会将x全部展开(如果x也是一个宏的话)，然后再传给TO_STRING1转换为字符串，现在你可以这样：&lt;br /&gt;&amp;nbsp;&amp;nbsp; const char *str = TO_STRING( PARAM( ADDPARAM( 1 ) ) );去一探PARAM展开后的样子。&lt;/p&gt;&#xD;
&lt;p&gt;7. 一个很重要的补充：就像我在第一点说的那样，如果一个像函数的宏在使用时没有出现括号，那么预处理器只是&lt;br /&gt;&amp;nbsp;&amp;nbsp; 将这个宏作为一般的符号处理(那就是不处理)。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;我们来见识一下宏是如何帮助我们自动产生代码的。如我所说，宏是在符号层次产生代码。我在分析Boost.Function&lt;br /&gt;模块时，因为它使用了大量的宏(宏嵌套，再嵌套)，导致我压根没看明白代码。后来发现了一个小型的模板库ttl，说的&lt;br /&gt;是开发一些小型组件去取代部分Boost(这是一个好理由，因为Boost确实太大)。同样，这个库也包含了一个function库。&lt;br /&gt;这里的function也就是我之前提到的functor。ttl.function库里为了自动产生很多类似的代码，使用了一个宏：&lt;/p&gt;&#xD;
&lt;p&gt;#define TTL_FUNC_BUILD_FUNCTOR_CALLER(n)&amp;nbsp; \&lt;br /&gt;&amp;nbsp;template&amp;lt; typename R, TTL_TPARAMS(n) &amp;gt; \&lt;br /&gt;&amp;nbsp;struct functor_caller_base##n \&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ///...&lt;br /&gt;该宏的最终目的是：通过类似于TTL_FUNC_BUILD_FUNCTOR_CALLER(1)的调用方式，自动产生很多functor_caller_base模板：&lt;br /&gt;template &amp;lt;typename R, typename T1&amp;gt; struct functor_caller_base1&lt;br /&gt;template &amp;lt;typename R, typename T1, typename T2&amp;gt; struct functor_caller_base2&lt;br /&gt;template &amp;lt;typename R, typename T1, typename T2, typename T3&amp;gt; struct functor_caller_base3&lt;br /&gt;///... &lt;br /&gt;那么，核心部分在于TTL_TPARAMS(n)这个宏，可以看出这个宏最终产生的是：&lt;br /&gt;typename T1&lt;br /&gt;typename T1, typename T2&lt;br /&gt;typename T1, typename T2, typename T3&lt;br /&gt;///...&lt;br /&gt;我们不妨分析TTL_TPARAMS(n)的整个过程。分析宏主要把握我以上提到的一些要点即可。以下过程我建议你翻着ttl的代码，&lt;br /&gt;相关代码文件：function.hpp, macro_params.hpp, macro_repeat.hpp, macro_misc.hpp, macro_counter.hpp。&lt;/p&gt;&#xD;
&lt;p&gt;so, here we go &lt;/p&gt;&#xD;
&lt;p&gt;分析过程，逐层分析，逐层展开，例如TTL_TPARAMS(1)：&lt;/p&gt;&#xD;
&lt;p&gt;#define TTL_TPARAMS(n) TTL_TPARAMSX(n,T)&amp;nbsp; &lt;br /&gt;=&amp;gt; TTL_TPARAMSX( 1, T )&lt;br /&gt;#define TTL_TPARAMSX(n,t) TTL_REPEAT(n, TTL_TPARAM, TTL_TPARAM_END, t)&lt;br /&gt;=&amp;gt; TTL_REPEAT( 1, TTL_TPARAM, TTL_TPARAM_END, T )&lt;br /&gt;#define TTL_TPARAM(n,t) typename t##n, &lt;br /&gt;#define TTL_TPARAM_END(n,t) typename t##n&lt;br /&gt;#define TTL_REPEAT(n, m, l, p) TTL_APPEND(TTL_REPEAT_, TTL_DEC(n))(m,l,p) TTL_APPEND(TTL_LAST_REPEAT_,n)(l,p)&lt;br /&gt;注意，TTL_TPARAM, TTL_TPARAM_END虽然也是两个宏，他们被作为TTL_REPEAT宏的参数，按照prescan规则，似乎应该先将&lt;br /&gt;这两个宏展开再传给TTL_REPEAT。但是，如同我在前面重点提到的，这两个宏是function-like macro，使用时需要加括号，&lt;br /&gt;如果没加括号，则不当作宏处理。因此，展开TTL_REPEAT时，应该为：&lt;br /&gt;=&amp;gt; TTL_APPEND( TTL_REPEAT_, TTL_DEC(1))(TTL_TPARAM,TTL_TPARAM_END,T) TTL_APPEND( TTL_LAST_REPEAT_,1)(&lt;br /&gt;TTL_TPARAM_END,T)&lt;br /&gt;这个宏体看起来很复杂，仔细分析下，可以分为两部分：&lt;br /&gt;TTL_APPEND( TTL_REPEAT_, TTL_DEC(1))(TTL_TPARAM,TTL_TPARAM_END,T)以及&lt;br /&gt;TTL_APPEND( TTL_LAST_REPEAT_,1)(TTL_TPARAM_END,T)&lt;br /&gt;先分析第一部分：&lt;br /&gt;#define TTL_APPEND( x, y ) TTL_APPEND1(x,y) //先展开x,y再将x,y连接起来&lt;br /&gt;#define TTL_APPEND1( x, y ) x ## y&lt;br /&gt;#define TTL_DEC(n) TTL_APPEND(TTL_CNTDEC_, n)&lt;br /&gt;根据先展开参数的原则，会先展开TTL_DEC(1)&lt;br /&gt;=&amp;gt; TTL_APPEND(TTL_CNTDEC_,1) =&amp;gt; TTL_CNTDEC_1 &lt;br /&gt;#define TTL_CNTDEC_1 0&amp;nbsp; 注意，TTL_CNTDEC_不是宏，TTL_CNTDEC_1是一个宏。&lt;br /&gt;=&amp;gt; 0 ， 也就是说，TTL_DEC(1)最终被展开为0。回到TTL_APPEND部分：&lt;br /&gt;=&amp;gt; TTL_REPEAT_0 (TTL_TPARAM,TTL_TPARAM_END,T) &lt;br /&gt;#define TTL_REPEAT_0(m,l,p)&lt;br /&gt;TTL_REPEAT_0这个宏为空，那么，上面说的第一部分被忽略，现在只剩下第二部分：&lt;br /&gt;TTL_APPEND( TTL_LAST_REPEAT_,1)(TTL_TPARAM_END,T)&lt;br /&gt;=&amp;gt; TTL_LAST_REPEAT_1 (TTL_TPARAM_END,T) // TTL_APPEND将TTL_LAST_REPEAT_和1合并起来&lt;br /&gt;#define TTL_LAST_REPEAT_1(m,p) m(1,p)&lt;br /&gt;=&amp;gt; TTL_TPARAM_END( 1, T )&lt;br /&gt;#define TTL_TPARAM_END(n,t) typename t##n&lt;br /&gt;=&amp;gt; typename T1&amp;nbsp; 展开完毕。&lt;/p&gt;&#xD;
&lt;p&gt;虽然我们分析出来了，但是这其实并不是我们想要的。我们应该从那些宏里去获取作者关于宏的编程思想。很好地使用宏&lt;br /&gt;看上去似乎是一些偏门的奇技淫巧，但是他确实可以让我们编码更自动化。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;转自：http://www.kuqin.com/language/20080319/4797.html&lt;/p&gt;&lt;img src="http://www.cnblogs.com/sevenyuan/aggbug/1907290.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/sevenyuan/archive/2010/12/15/1907290.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/sevenyuan/archive/2010/12/15/1907288.html</id><title type="text">C/C++ typedef</title><summary type="text">第一、四个用途用途一：定义一种类型的别名，而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如：char* pa, pb; // 这多数不符合我们的意图，它只声明了一个指向字符变量的指针， // 和一个字符变量；以下则可行：typedef char* PCHAR; // 一般用大写PCHAR pa, pb; // 可行，同时声明了两个指向字符变量的指针虽然：char *pa, *pb;也可行，但相对来说没有用typedef的形式直观，尤其在需要大量指针的地方，typedef的方式更省事。用途二：用在旧的C的代码中（具体多旧没有查），帮助struct。以前的代码中，声明struct新对象</summary><published>2010-12-15T13:41:00Z</published><updated>2010-12-15T13:41:00Z</updated><author><name>Seven_Yuan</name><uri>http://www.cnblogs.com/sevenyuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/15/1907288.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/15/1907288.html"/><content type="html">&lt;p&gt;&lt;strong&gt;&lt;span style="font-size: 14pt;"&gt;第一、四个用途&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;用途一：&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;定义一种类型的别名，而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如：&lt;br /&gt;char* pa, pb; // 这多数不符合我们的意图，它只声明了一个指向字符变量的指针， &lt;br /&gt;// 和一个字符变量；&lt;br /&gt;以下则可行：&lt;br /&gt;typedef char* PCHAR; // 一般用大写&lt;br /&gt;PCHAR pa, pb; // 可行，同时声明了两个指向字符变量的指针&lt;br /&gt;虽然：&lt;br /&gt;char *pa, *pb;&lt;br /&gt;也可行，但相对来说没有用typedef的形式直观，尤其在需要大量指针的地方，typedef的方式更省事。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;用途二：&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;用在旧的C的代码中（具体多旧没有查），帮助struct。以前的代码中，声明struct新对象时，必须要带上struct，即形式为： struct 结构名 对象名，如：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt; tagPOINT1&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; x;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; y;&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt; tagPOINT1 p1; &lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;而在C++中，则可以直接写：结构名 对象名，即：&lt;br /&gt;tagPOINT1 p1;&lt;/p&gt;&#xD;
&lt;p&gt;估计某人觉得经常多写一个struct太麻烦了，于是就发明了：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #000000;"&gt;typedef &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt; tagPOINT&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; x;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; y;&lt;br /&gt;}POINT;&lt;br /&gt;&lt;br /&gt;POINT p1; &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 这样就比原来的方式少写了一个struct，比较省事，尤其在大量使用的时候&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;或许，在C++中，typedef的这种用途二不是很大，但是理解了它，对掌握以前的旧代码还是有帮助的，毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;用途三：&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;用typedef来定义与平台无关的类型。&lt;br /&gt;比如定义一个叫 REAL 的浮点类型，在目标平台一上，让它表示最高精度的类型为：&lt;br /&gt;typedef long double REAL; &lt;br /&gt;在不支持 long double 的平台二上，改为：&lt;br /&gt;typedef double REAL; &lt;br /&gt;在连 double 都不支持的平台三上，改为：&lt;br /&gt;typedef float REAL; &lt;br /&gt;也就是说，当跨平台时，只要改下 typedef 本身就行，不用对其他源码做任何修改。&lt;br /&gt;标准库就广泛使用了这个技巧，比如size_t。&lt;br /&gt;另外，因为typedef是定义了一种类型的新别名，不是简单的字符串替换，所以它比宏来得稳健（虽然用宏有时也可以完成以上的用途）。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;用途四：&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;为复杂的声明定义一个新的简单的别名。方法是：在原来的声明里逐步用别名替换一部分复杂声明，如此循环，把带变量名的部分留到最后替换，得到的就是原声明的最简化版。举例：&lt;/p&gt;&#xD;
&lt;p&gt;1. 原声明：int *(*a[5])(int, char*);&lt;br /&gt;变量名为a，直接用一个新别名pFun替换a就可以了：&lt;br /&gt;typedef int *(*pFun)(int, char*); &lt;br /&gt;原声明的最简化版：&lt;br /&gt;pFun a[5]; &lt;/p&gt;&#xD;
&lt;p&gt;2. 原声明：void (*b[10]) (void (*)());&lt;br /&gt;变量名为b，先替换右边部分括号里的，pFunParam为别名一：&lt;br /&gt;typedef void (*pFunParam)();&lt;br /&gt;再替换左边的变量b，pFunx为别名二：&lt;br /&gt;typedef void (*pFunx)(pFunParam);&lt;br /&gt;原声明的最简化版：&lt;br /&gt;pFunx b[10];&lt;/p&gt;&#xD;
&lt;p&gt;3. 原声明：doube(*)() (*e)[9]; &lt;br /&gt;变量名为e，先替换左边部分，pFuny为别名一：&lt;br /&gt;typedef double(*pFuny)();&lt;br /&gt;再替换右边的变量e，pFunParamy为别名二&lt;br /&gt;typedef pFuny (*pFunParamy)[9];&lt;br /&gt;原声明的最简化版：&lt;br /&gt;pFunParamy e; &lt;/p&gt;&#xD;
&lt;p&gt;理解复杂声明可用的&amp;ldquo;右左法则&amp;rdquo;：&lt;br /&gt;从变量名看起，先往右，再往左，碰到一个圆括号就调转阅读的方向；括号内分析完就跳出括号，还是按先右后左的顺序，如此循环，直到整个声明分析完。举例：&lt;br /&gt;int (*func)(int *p);&lt;br /&gt;首先找到变量名func，外面有一对圆括号，而且左边是一个*号，这说明func是一个指针；然后跳出这个圆括号，先看右边，又遇到圆括号，这说明(*func)是一个函数，所以func是一个指向这类函数的指针，即函数指针，这类函数具有int*类型的形参，返回值类型是int。&lt;br /&gt;int (*func[5])(int *);&lt;br /&gt;func右边是一个[]运算符，说明func是具有5个元素的数组；func的左边有一个*，说明func的元素是指针（注意这里的*不是修饰func，而是修饰func[5]的，原因是[]运算符优先级比*高，func先跟[]结合）。跳出这个括号，看右边，又遇到圆括号，说明func数组的元素是函数类型的指针，它指向的函数具有int*类型的形参，返回值类型为int。&lt;/p&gt;&#xD;
&lt;p&gt;也可以记住2个模式：&lt;br /&gt;type (*)(....)函数指针 &lt;br /&gt;type (*)[]数组指针 &lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-size: 14pt;"&gt;第二、两大陷阱&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;陷阱一：&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;记住，typedef是定义了一种类型的新别名，不同于宏，它不是简单的字符串替换。比如：&lt;br /&gt;先定义：&lt;br /&gt;typedef char* PSTR;&lt;br /&gt;然后：&lt;br /&gt;int mystrcmp(const PSTR, const PSTR);&lt;/p&gt;&#xD;
&lt;p&gt;const PSTR实际上相当于const char*吗？不是的，它实际上相当于char* const。&lt;br /&gt;原因在于const给予了整个指针本身以常量性，也就是形成了常量指针char* const。&lt;br /&gt;简单来说，记住当const和typedef一起出现时，typedef不会是简单的字符串替换就行。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;陷阱二：&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;typedef在语法上是一个存储类的关键字（如auto、extern、mutable、static、register等一样），虽然它并不真正影响对象的存储特性，如：&lt;br /&gt;typedef static int INT2; //不可行&lt;br /&gt;编译将失败，会提示&amp;ldquo;指定了一个以上的存储类&amp;rdquo;。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;以上资料出自：&lt;/strong&gt;&lt;a href="http://blog.sina.com.cn/s/blog_4826f7970100074k.html" target="_blank"&gt;http://blog.sina.com.cn/s/blog_4826f7970100074k.html&lt;/a&gt;&amp;nbsp;作者：赤龙&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-size: 14pt;"&gt;第三、typedef 与 #define的区别&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;案例一：&lt;/p&gt;&#xD;
&lt;p&gt;通常讲，typedef要比#define要好，特别是在有指针的场合。请看例子：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #000000;"&gt;typedef &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;pStr1;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#define&lt;/span&gt;&lt;span style="color: #000000;"&gt; pStr2 char *;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;pStr1 s1, s2;&lt;br /&gt;pStr2 s3, s4;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在上述的变量定义中，s1、s2、s3都被定义为char *，而s4则定义成了char，不是我们所预期的指针变量，根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字。&lt;/p&gt;&#xD;
&lt;p&gt;案例二：&lt;/p&gt;&#xD;
&lt;p&gt;下面的代码中编译器会报一个错误，你知道是哪个语句错了吗？&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #000000;"&gt;typedef &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; pStr;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[&lt;/span&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&lt;span style="color: #000000;"&gt;] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;abc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;p1 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; pStr p2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;p1&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;p2&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;是p2++出错了。这个问题再一次提醒我们：typedef和#define不同，它不是简单的文本替换。上述代码中const pStr p2并不等于const char * p2。const pStr p2和const long x本质上没有区别，都是对变量进行只读限制，只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此，const pStr p2的含义是：限定数据类型为char *的变量p2为只读，因此p2++错误。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-size: 14pt;"&gt;第四部分资料：使用 typedef 抑制劣质代码&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;作者：Danny Kalev&lt;br /&gt;编译：MTT 工作室&lt;/p&gt;&#xD;
&lt;p&gt;原文出处：Using typedef to Curb Miscreant Code&lt;/p&gt;&#xD;
&lt;table style="border-collapse: collapse;" border="0" cellspacing="0" cellpadding="0" width="92%" height="61"&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td width="100%" height="61"&gt;&lt;strong&gt;摘要：&lt;/strong&gt;Typedef 声明有助于创建平台无关类型，甚至能隐藏复杂和难以理解的语法。不管怎样，使用 typedef 能为代码带来意想不到的好处，通过本文你可以学习用 typedef 避免缺欠，从而使代码更健壮。&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;p&gt;typedef 声明，简称 typedef，为现有类型创建一个新的名字。比如人们常常使用 typedef 来编写更美观和可读的代码。所谓美观，意指 typedef 能隐藏笨拙的语法构造以及平台相关的数据类型，从而增强可移植性和以及未来的可维护性。本文下面将竭尽全力来揭示 typedef 强大功能以及如何避免一些常见的陷阱。&lt;/p&gt;&#xD;
&lt;p&gt;Q：如何创建平台无关的数据类型，隐藏笨拙且难以理解的语法?&lt;/p&gt;&#xD;
&lt;p&gt;A： 使用 typedefs 为现有类型创建同义字。 &lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;定义易于记忆的类型名&lt;/strong&gt;&lt;br /&gt;　　typedef 使用最多的地方是创建易于记忆的类型名，用它来归档程序员的意图。类型出现在所声明的变量名字中，位于 ''typedef'' 关键字右边。例如：&lt;/p&gt;&#xD;
&lt;pre&gt;typedef int size;&lt;/pre&gt;&#xD;
&lt;p&gt;此声明定义了一个 int 的同义字，名字为 size。注意 typedef 并不创建新的类型。它仅仅为现有类型添加一个同义字。你可以在任何需要 int 的上下文中使用 size：&lt;/p&gt;&#xD;
&lt;pre&gt;void measure(size * psz); size array[4];size len = file.getlength();std::vector &amp;lt;size&amp;gt; vs; &lt;/pre&gt;&#xD;
&lt;p&gt;typedef 还可以掩饰符合类型，如指针和数组。例如，你不用象下面这样重复定义有 81 个字符元素的数组：&lt;/p&gt;&#xD;
&lt;pre&gt;char line[81];char text[81];&lt;/pre&gt;&#xD;
&lt;p&gt;定义一个 typedef，每当要用到相同类型和大小的数组时，可以这样：&lt;/p&gt;&#xD;
&lt;pre&gt;typedef char Line[81]; Line text, secondline;getline(text);&lt;/pre&gt;&#xD;
&lt;p&gt;同样，可以象下面这样隐藏指针语法：&lt;/p&gt;&#xD;
&lt;pre&gt;typedef char * pstr;int mystrcmp(pstr, pstr);&lt;/pre&gt;&#xD;
&lt;p&gt;这里将带我们到达第一个 typedef 陷阱。标准函数 strcmp()有两个&amp;lsquo;const char *&amp;rsquo;类型的参数。因此，它可能会误导人们象下面这样声明 mystrcmp()：&lt;/p&gt;&#xD;
&lt;pre&gt;int mystrcmp(const pstr, const pstr); &lt;/pre&gt;&#xD;
&lt;p&gt;这是错误的，按照顺序，&amp;lsquo;const pstr&amp;rsquo;被解释为&amp;lsquo;char * const&amp;rsquo;（一个指向 char 的常量指针），而不是&amp;lsquo;const char *&amp;rsquo;（指向常量 char 的指针）。这个问题很容易解决：&lt;/p&gt;&#xD;
&lt;pre&gt;typedef const char * cpstr; int mystrcmp(cpstr, cpstr); // 现在是正确的&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;strong&gt;记住：&lt;/strong&gt;不管什么时候，只要为指针声明 typedef，那么都要在最终的 typedef 名称中加一个 const，以使得该指针本身是常量，而不是对象。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;代码简化&lt;/strong&gt;&lt;br /&gt;　　上面讨论的 typedef 行为有点像 #define 宏，用其实际类型替代同义字。不同点是 typedef 在编译时被解释，因此让编译器来应付超越预处理器能力的文本替换。例如：&lt;/p&gt;&#xD;
&lt;pre&gt;typedef int (*PF) (const char *, const char *);&lt;/pre&gt;&#xD;
&lt;p&gt;这个声明引入了 PF 类型作为函数指针的同义字，该函数有两个 const char * 类型的参数以及一个 int 类型的返回值。如果要使用下列形式的函数声明，那么上述这个 typedef 是不可或缺的：&lt;/p&gt;&#xD;
&lt;pre&gt;PF Register(PF pf);&lt;/pre&gt;&#xD;
&lt;p&gt;Register() 的参数是一个 PF 类型的回调函数，返回某个函数的地址，其署名与先前注册的名字相同。做一次深呼吸。下面我展示一下如果不用 typedef，我们是如何实现这个声明的：&lt;/p&gt;&#xD;
&lt;pre&gt;int (*Register (int (*pf)(const char *, const char *))) (const char *, const char *); &lt;/pre&gt;&#xD;
&lt;p&gt;很少有程序员理解它是什么意思，更不用说这种费解的代码所带来的出错风险了。显然，这里使用 typedef 不是一种特权，而是一种必需。持怀疑态度的人可能会问：&amp;ldquo;OK，有人还会写这样的代码吗？&amp;rdquo;，快速浏览一下揭示&lt;strong&gt;&lt;em&gt; &lt;/em&gt;&lt;/strong&gt;signal()函数的头文件 &amp;lt;csinal&amp;gt;，一个有同样接口的函数。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;typedef 和存储类关键字（storage class specifier）&lt;/strong&gt;&lt;br /&gt;　　这种说法是不是有点令人惊讶，typedef 就像 auto，extern，mutable，static，和 register 一样，是一个存储类关键字。这并是说 typedef 会真正影响对象的存储特性；它只是说在语句构成上，typedef 声明看起来象 static，extern 等类型的变量声明。下面将带到第二个陷阱：&lt;/p&gt;&#xD;
&lt;pre&gt;typedef register int FAST_COUNTER; // 错误&lt;/pre&gt;&#xD;
&lt;p&gt;编译通不过。问题出在你不能在声明中有多个存储类关键字。因为符号 typedef 已经占据了存储类关键字的位置，在 typedef 声明中不能用 register（或任何其它存储类关键字）。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;促进跨平台开发&lt;/strong&gt;&lt;br /&gt;　　typedef 有另外一个重要的用途，那就是定义机器无关的类型，例如，你可以定义一个叫 REAL 的浮点类型，在目标机器上它可以i获得最高的精度：&lt;/p&gt;&#xD;
&lt;pre&gt;typedef long double REAL; &lt;/pre&gt;&#xD;
&lt;p&gt;在不支持 long double 的机器上，该 typedef 看起来会是下面这样：&lt;/p&gt;&#xD;
&lt;pre&gt;typedef double REAL; &lt;/pre&gt;&#xD;
&lt;p&gt;并且，在连 double 都不支持的机器上，该 typedef 看起来会是这样： 、&lt;/p&gt;&#xD;
&lt;pre&gt;typedef float REAL; &lt;/pre&gt;&#xD;
&lt;p&gt;你不用对源代码做任何修改，便可以在每一种平台上编译这个使用 REAL 类型的应用程序。唯一要改的是 typedef 本身。在大多数情况下，甚至这个微小的变动完全都可以通过奇妙的条件编译来自动实现。不是吗? 标准库广泛地使用 typedef 来创建这样的平台无关类型：size_t，ptrdiff 和 fpos_t 就是其中的例子。此外，象 std::string 和 std::ofstream 这样的 typedef 还隐藏了长长的，难以理解的模板特化语法，例如：basic_string&amp;lt;char, char_traits&amp;lt;char&amp;gt;，allocator&amp;lt;char&amp;gt;&amp;gt; 和 basic_ofstream&amp;lt;char, char_traits&amp;lt;char&amp;gt;&amp;gt;。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;以上转自：http://www.kuqin.com/language/20090322/41866.html&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;typedef &amp;amp; 结构的问题 &lt;br /&gt;&lt;/strong&gt;　　 &lt;/p&gt;&#xD;
&lt;p&gt;（&lt;strong&gt;1）、typedef的最简单使用 &lt;br /&gt;　　typedef long byte_4; &lt;br /&gt;　　给已知数据类型long起个新名字，叫byte_4。 &lt;br /&gt;&lt;/strong&gt;&lt;strong&gt;（2）、 typedef与结构结合使用 &lt;br /&gt;　　typedef struct tagMyStruct &lt;br /&gt;　　{ &lt;br /&gt;　　int iNum; &lt;br /&gt;　　long lLength; &lt;br /&gt;　　} MyStruct; &lt;br /&gt;　　这语句实际上完成两个操作： &lt;br /&gt;1) 定义一个新的结构类型 &lt;br /&gt;　　struct tagMyStruct &lt;br /&gt;　　{ &lt;br /&gt;　　int iNum; &lt;br /&gt;　　long lLength; &lt;br /&gt;　　}; &lt;br /&gt;&lt;/strong&gt;　　分析：tagMyStruct称为&amp;ldquo;tag&amp;rdquo;，即&amp;ldquo;标签&amp;rdquo;，实际上是一个临时名字，struct 关键字和tagMyStruct一起，构成了这个结构类型，不论是否有typedef，这个结构都存在。 &lt;br /&gt;　　我们可以用struct tagMyStruct varName来定义变量，但要注意，使用tagMyStruct varName来定义变量是不对的，因为struct 和tagMyStruct合在一起才能表示一个结构类型。 &lt;br /&gt;&lt;strong&gt;2) typedef为这个新的结构起了一个名字，叫MyStruct。 &lt;br /&gt;&lt;/strong&gt;　　typedef struct tagMyStruct MyStruct; &lt;br /&gt;　　&lt;strong&gt;因此，MyStruct实际上相当于struct tagMyStruct，我们可以使用MyStruct varName来定义变量。&lt;/strong&gt; &lt;br /&gt;&lt;strong&gt;3)、规范做法：&lt;/strong&gt; &lt;br /&gt;　　struct tagNode &lt;br /&gt;　　{ &lt;br /&gt;　　char *pItem; &lt;br /&gt;　　struct tagNode *pNext; &lt;br /&gt;　　}; &lt;br /&gt;　　typedef struct tagNode *pNode; &lt;br /&gt;&lt;strong&gt;3. typedef &amp;amp; #define的问题 &lt;br /&gt;　　有下面两种定义pStr数据类型的方法，两者有什么不同？哪一种更好一点？ &lt;br /&gt;　　typedef char* pStr; &lt;br /&gt;　　#define pStr char*;&lt;/strong&gt; &lt;br /&gt;　　答案与分析： &lt;br /&gt;　　&lt;strong&gt;通常讲，typedef要比#define要好，特别是在有指针的场合。请看例子： &lt;br /&gt;　　typedef char* pStr1; &lt;br /&gt;　　#define pStr2 char * &lt;br /&gt;　　pStr1 s1, s2; &lt;br /&gt;　　pStr2 s3, s4; &lt;br /&gt;　　在上述的变量定义中，s1、s2、s3都被定义为char *，而s4则定义成了char，不是我们所预期的指针变量，根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字。 &lt;br /&gt;&lt;/strong&gt;　　上例中define语句必须写成 pStr2 s3, *s4; 这这样才能正常执行。 &lt;br /&gt;　　#define用法例子： &lt;br /&gt;　　#define f(x) x*x &lt;br /&gt;　　main( ) &lt;br /&gt;　　{ &lt;br /&gt;　　int a=6，b=2，c； &lt;br /&gt;　　c=f(a) / f(b)； &lt;br /&gt;　　printf("%d &lt;a&gt;\\n&lt;/a&gt;"，c)； &lt;br /&gt;　　} &lt;br /&gt;　　以下程序的输出结果是: 36。 &lt;br /&gt;　　因为如此原因，在许多C语言编程规范中提到使用#define定义时，如果定义中包含表达式，必须使用括号，则上述定义应该如下定义才对： &lt;br /&gt;　　#define f(x) (x*x) &lt;br /&gt;　　当然，如果你使用typedef就没有这样的问题。 &lt;br /&gt;4. typedef &amp;amp; #define的另一例 &lt;br /&gt;　　下面的代码中编译器会报一个错误，你知道是哪个语句错了吗？ &lt;br /&gt;　　typedef char * pStr; &lt;br /&gt;　　char string[4] = "abc"; &lt;br /&gt;　　const char *p1 = string; &lt;br /&gt;　　const pStr p2 = string; &lt;br /&gt;　　p1++; &lt;br /&gt;　　p2++; &lt;br /&gt;　　答案与分析： &lt;br /&gt;　　是p2++出错了。这个问题再一次提醒我们：typedef和#define不同，它不是简单的文本替换。上述代码中const pStr p2并不等于const char * p2。const pStr p2和const long x本质上没有区别，都是对变量进行只读限制，只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此，const pStr p2的含义是：限定数据类型为char *的变量p2为只读，因此p2++错误。 &lt;br /&gt;　　#define与typedef引申谈 &lt;br /&gt;　　1) #define宏定义有一个特别的长处：可以使用 #ifdef ,#ifndef等来进行逻辑判断，还可以使用#undef来取消定义。 &lt;br /&gt;　　2) typedef也有一个特别的长处：它符合范围规则，使用typedef定义的变量类型其作用范围限制在所定义的函数或者文件内（取决于此变量定义的位置），而宏定义则没有这种特性。 &lt;br /&gt;5. typedef &amp;amp; 复杂的变量声明 &lt;br /&gt;　　在编程实践中，尤其是看别人代码的时候，常常会遇到比较复杂的变量声明,使用typedef作简化自有其价值，比如： &lt;br /&gt;　　下面是三个变量的声明，我想使用typdef分别给它们定义一个别名，请问该如何做？ &lt;br /&gt;　　&amp;gt;1：int *(*a[5])(int, char*); &lt;br /&gt;　　&amp;gt;2：void (*b[10]) (void (*)()); &lt;br /&gt;　　&amp;gt;3. double(*)() (*pa)[9]; &lt;br /&gt;　　答案与分析： &lt;br /&gt;　　对复杂变量建立一个类型别名的方法很简单，你只要在传统的变量声明表达式里用类型名替代变量名，然后把关键字typedef加在该语句的开头就行了。 &lt;br /&gt;　　&amp;gt;1：int *(*a[5])(int, char*); &lt;br /&gt;　　//pFun是我们建的一个类型别名 &lt;br /&gt;　　typedef int *(*pFun)(int, char*); &lt;br /&gt;　　//使用定义的新类型来声明对象，等价于int* (*a[5])(int, char*); &lt;br /&gt;　　pFun a[5]; &lt;br /&gt;　　&amp;gt;2：void (*b[10]) (void (*)()); &lt;br /&gt;　　//首先为上面表达式蓝色部分声明一个新类型 &lt;br /&gt;　　typedef void (*pFunParam)(); &lt;br /&gt;　　//整体声明一个新类型 &lt;br /&gt;　　typedef void (*pFun)(pFunParam); &lt;br /&gt;　　//使用定义的新类型来声明对象，等价于void (*b[10]) (void (*)()); &lt;br /&gt;　　pFun b[10]; &lt;br /&gt;　　&amp;gt;3. double(*(*pa)[9])(); &lt;br /&gt;　　//首先为上面表达式蓝色部分声明一个新类型 &lt;br /&gt;　　typedef double(*pFun)(); &lt;br /&gt;　　//整体声明一个新类型 &lt;br /&gt;　　typedef pFun (*pFunParam)[9]; &lt;br /&gt;　　//使用定义的新类型来声明对象，等价于double(*(*pa)[9])(); &lt;br /&gt;　　pFunParam pa;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/sevenyuan/aggbug/1907288.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/sevenyuan/archive/2010/12/15/1907288.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/sevenyuan/archive/2010/12/10/1902145.html</id><title type="text">python: string的操作函数</title><summary type="text">转自:http://www.91linux.com/html/article/program/python/20090804/17759.htm在python有各种各样的string操作函数。在历史上string类在python中经历了一段轮回的历史。在最开始的时候，python有一个专门的string的module，要使用string的方法要先import，但后来由于众多的python使用者的建议，从python2.0开始，string方法改为用S.method()的形式调用，只要S是一个字符串对象就可以这样使用，而不用import。同时为了保持向后兼容，现在的python中仍然保留了一个s</summary><published>2010-12-10T03:55:00Z</published><updated>2010-12-10T03:55:00Z</updated><author><name>Seven_Yuan</name><uri>http://www.cnblogs.com/sevenyuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/10/1902145.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/10/1902145.html"/><content type="html">&lt;p&gt;转自:http://www.91linux.com/html/article/program/python/20090804/17759.htm&lt;/p&gt;&#xD;
&lt;p&gt;在python有各种各样的string操作函数。在历史上string类在python中经历了一段轮回的历史。在最开始的时候，python有一个专门的string的module，要使用string的方法要先import，但后来由于众多的python使用者的建议，从python2.0开始，string方法改为用S.method()的形式调用，只要S是一个字符串对象就可以这样使用，而不用import。同时为了保持向后兼容，现在的python中仍然保留了一个string的module，其中定义的方法与S.method()是相同的，这些方法都最后都指向了用S.method()调用的函数。要注意，S.method()能调用的方法比string的module中的多，比如isdigit()、istitle()等就只能用S.method()的方式调用。&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;对一个字符串对象，首先想到的操作可能就是计算它有多少个字符组成，很容易想到用S.len()，但这是错的，应该是len(S)。因为len()是内置函数，包括在__builtin__模块中。python不把len()包含在string类型中，乍看起来好像有点不可理解，其实一切有其合理的逻辑在里头。len()不仅可以计算字符串中的字符数，还可以计算list的成员数，tuple的成员数等等，因此单单把len()算在string里是不合适，因此一是可以把len()作为通用函数，用重载实现对不同类型的操作，还有就是可以在每种有len()运算的类型中都要包含一个len()函数。python选择的是第一种解决办法。类似的还有str(arg)函数，它把arg用string类型表示出来。 &lt;/p&gt;&#xD;
&lt;p&gt;字符串中字符大小写的变换： &lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;S.lower() #小写 &lt;br /&gt;S.upper() #大写 &lt;br /&gt;S.swapcase() #大小写互换 &lt;br /&gt;S.capitalize() #首字母大写 &lt;br /&gt;String.capwords(S) &lt;br /&gt;#这是模块中的方法。它把S用split()函数分开，然后用capitalize()把首字母变成大写，最后用join()合并到一起 &lt;br /&gt;S.title() #只有首字母大写，其余为小写，模块中没有这个方法 &lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;字符串在输出时的对齐： &lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;S.ljust(width,[fillchar]) &lt;br /&gt;#输出width个字符，S左对齐，不足部分用fillchar填充，默认的为空格。 &lt;br /&gt;S.rjust(width,[fillchar]) #右对齐 &lt;br /&gt;S.center(width, [fillchar]) #中间对齐 &lt;br /&gt;S.zfill(width) #把S变成width长，并在右对齐，不足部分用0补足 &lt;/p&gt;&#xD;
&lt;p&gt;字符串中的搜索和替换： &lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;S.find(substr, [start, [end]]) &lt;br /&gt;#返回S中出现substr的第一个字母的标号，如果S中没有substr则返回-1。start和end作用就相当于在S[start:end]中搜索 &lt;br /&gt;S.index(substr, [start, [end]]) &lt;br /&gt;#与find()相同，只是在S中没有substr时，会返回一个运行时错误 &lt;br /&gt;S.rfind(substr, [start, [end]]) &lt;br /&gt;#返回S中最后出现的substr的第一个字母的标号，如果S中没有substr则返回-1，也就是说从右边算起的第一次出现的substr的首字母标号 &lt;br /&gt;S.rindex(substr, [start, [end]]) &lt;br /&gt;S.count(substr, [start, [end]]) #计算substr在S中出现的次数 &lt;br /&gt;S.replace(oldstr, newstr, [count]) &lt;br /&gt;#把S中的oldstar替换为newstr，count为替换次数。这是替换的通用形式，还有一些函数进行特殊字符的替换 &lt;br /&gt;S.strip([chars]) &lt;br /&gt;#把S中前后chars中有的字符全部去掉，可以理解为把S前后chars替换为None &lt;br /&gt;S.lstrip([chars]) &lt;br /&gt;S.rstrip([chars]) &lt;br /&gt;S.expandtabs([tabsize]) &lt;br /&gt;#把S中的tab字符替换没空格，每个tab替换为tabsize个空格，默认是8个 &lt;br /&gt;字符串的分割和组合： &lt;/p&gt;&#xD;
&lt;p&gt;S.split([sep, [maxsplit]]) &lt;br /&gt;#以sep为分隔符，把S分成一个list。maxsplit表示分割的次数。默认的分割符为空白字符 &lt;br /&gt;S.rsplit([sep, [maxsplit]]) &lt;br /&gt;S.splitlines([keepends]) &lt;br /&gt;#把S按照行分割符分为一个list，keepends是一个bool值，如果为真每行后而会保留行分割符。 &lt;br /&gt;S.join(seq) #把seq代表的序列──字符串序列，用S连接起来&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;字符串的mapping，这一功能包含两个函数： &lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;String.maketrans(from, to) &lt;br /&gt;#返回一个256个字符组成的翻译表，其中from中的字符被一一对应地转换成to，所以from和to必须是等长的。 &lt;br /&gt;S.translate(table[,deletechars]) &lt;br /&gt;#使用上面的函数产后的翻译表，把S进行翻译，并把deletechars中有的字符删掉。需要注意的是，如果S为unicode字符串，那么就不支持deletechars参数，可以使用把某个字符翻译为None的方式实现相同的功能。此外还可以使用codecs模块的功能来创建更加功能强大的翻译表。 &lt;br /&gt;字符串还有一对编码和解码的函数： &lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;S.encode([encoding,[errors]]) &lt;br /&gt;#其中encoding可以有多种值，比如gb2312 gbk gb18030 bz2 zlib big5 bzse64等都支持。errors默认值为"strict"，意思是UnicodeError。可能的值还有'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 和所有的通过codecs.register_error注册的值。这一部分内容涉及codecs模块，不是特明白 &lt;/p&gt;&#xD;
&lt;p&gt;S.decode([encoding,[errors]]) &lt;br /&gt;字符串的测试函数，这一类函数在string模块中没有，这些函数返回的都是bool值： &lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;S.startwith(prefix[,start[,end]]) &lt;br /&gt;#是否以prefix开头 &lt;br /&gt;S.endwith(suffix[,start[,end]]) &lt;br /&gt;#以suffix结尾 &lt;br /&gt;S.isalnum() &lt;br /&gt;#是否全是字母和数字，并至少有一个字符 &lt;br /&gt;S.isalpha() #是否全是字母，并至少有一个字符 &lt;br /&gt;S.isdigit() #是否全是数字，并至少有一个字符 &lt;br /&gt;S.isspace() #是否全是空白字符，并至少有一个字符 &lt;br /&gt;S.islower() #S中的字母是否全是小写 &lt;br /&gt;S.isupper() #S中的字母是否便是大写 &lt;br /&gt;S.istitle() #S是否是首字母大写的 &lt;/p&gt;&#xD;
&lt;p&gt;字符串类型转换函数，这几个函数只在string模块中有： &lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;string.atoi(s[,base]) &lt;br /&gt;#base默认为10，如果为0,那么s就可以是012或0x23这种形式的字符串，如果是16那么s就只能是0x23或0X12这种形式的字符串 &lt;br /&gt;string.atol(s[,base]) #转成long &lt;br /&gt;string.atof(s[,base]) #转成float &lt;/p&gt;&#xD;
&lt;p&gt;这里再强调一次，字符串对象是不可改变的，也就是说在python创建一个字符串后，你不能把这个字符中的某一部分改变。任何上面的函数改变了字符串后，都会返回一个新的字符串，原字串并没有变。其实这也是有变通的办法的，可以用S=list(S)这个函数把S变为由单个字符为成员的list，这样的话就可以使用S[3]='a'的方式改变值，然后再使用S=" ".join(S)还原成字符串 &lt;/p&gt;&lt;img src="http://www.cnblogs.com/sevenyuan/aggbug/1902145.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/sevenyuan/archive/2010/12/10/1902145.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/sevenyuan/archive/2010/12/10/1901769.html</id><title type="text">汉字和Unicode码(utf-8)之间的转换(Pack/Unpack)</title><summary type="text">保证你要转换的字符串编码为UTF8,如果不是,请iconv cnStr成utf8 恩, pack/unpack很强大,, 和c语言交换数据, 二进制方式的序列化,操作二进制文件.. etc… 附上format参数的说明:</summary><published>2010-12-09T17:20:00Z</published><updated>2010-12-09T17:20:00Z</updated><author><name>Seven_Yuan</name><uri>http://www.cnblogs.com/sevenyuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/10/1901769.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/10/1901769.html"/><content type="html">&lt;p&gt;保证你要转换的字符串编码为UTF8,如果不是,请iconv cnStr成utf8&lt;/p&gt;&#xD;
&lt;pre name="code" &gt;&lt;ol&gt;&lt;li&gt;&lt;span &gt;$cnStr&lt;/span&gt; &lt;span &gt;=&lt;/span&gt; &lt;span &gt;"中"&lt;/span&gt;&lt;span &gt;;&lt;/span&gt; &lt;span &gt;//utf8的中文&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;span &gt;//unicode&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span &gt;$code&lt;/span&gt; &lt;span &gt;=&lt;/span&gt; &lt;span &gt;unpack&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;"H6codes"&lt;/span&gt;&lt;span &gt;,&lt;/span&gt; &lt;span &gt;$cnStr&lt;/span&gt;&lt;span &gt;);&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;span &gt;//汉字&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span &gt;$cnStr&lt;/span&gt; &lt;span &gt;=&lt;/span&gt; &lt;span &gt;pack&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;"H6"&lt;/span&gt;&lt;span &gt;,&lt;/span&gt; &lt;span &gt;$code&lt;/span&gt;&lt;span &gt;[&lt;/span&gt;&lt;span &gt;'codes'&lt;/span&gt;&lt;span &gt;]);&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/pre&gt;&#xD;
&lt;p&gt;恩, pack/unpack很强大,, 和c语言交换数据, 二进制方式的序列化,操作二进制文件.. etc&amp;hellip;&lt;/p&gt;&#xD;
&lt;p&gt;附上format参数的说明:&lt;/p&gt;&#xD;
&lt;pre name="code" &gt;&lt;ol&gt;&lt;li&gt;a &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NUL-padded string, 即"\0"作为"空字符"的表示形式&lt;/li&gt;&lt;li&gt;A &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SPACE-padded string, 空格作为"空字符"的表示形式&lt;/li&gt;&lt;li&gt;h &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Hex string, low nibble first,升序位顺序&lt;/li&gt;&lt;li&gt;H &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Hex string, high nibble first,降序位顺序&lt;/li&gt;&lt;li&gt;c &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;signed char, 有符号单字节&lt;/li&gt;&lt;li&gt;C &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned char, 无符号单字节&lt;/li&gt;&lt;li&gt;s &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;signed short (always 16 bit, machine byte order)&lt;/li&gt;&lt;li&gt;S &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned short (always 16 bit, machine byte order)&lt;/li&gt;&lt;li&gt;n &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned short (always 16 bit, big endian byte order)&lt;/li&gt;&lt;li&gt;v &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned short (always 16 bit, little endian byte order)&lt;/li&gt;&lt;li&gt;i &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;signed integer (machine dependent size and byte order)&lt;/li&gt;&lt;li&gt;I &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned integer (machine dependent size and byte order)&lt;/li&gt;&lt;li&gt;l &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;signed long (always 32 bit, machine byte order)&lt;/li&gt;&lt;li&gt;L &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned long (always 32 bit, machine byte order)&lt;/li&gt;&lt;li&gt;N &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned long (always 32 bit, big endian byte order)&lt;/li&gt;&lt;li&gt;V &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned long (always 32 bit, little endian byte order)&lt;/li&gt;&lt;li&gt;f &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float (machine dependent size and representation)&lt;/li&gt;&lt;li&gt;d &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;double (machine dependent size and representation)&lt;/li&gt;&lt;li&gt;x &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NUL byte, 实际使用的时候作为跳过多少字节用,很有用&lt;/li&gt;&lt;li&gt;X &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Back up one byte, 后退1字节&lt;/li&gt;&lt;li&gt;@ &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NUL-fill to absolute position,实际使用的时候作为从开头跳到某字节用.&lt;/li&gt;&lt;/ol&gt;&lt;/pre&gt;&lt;img src="http://www.cnblogs.com/sevenyuan/aggbug/1901769.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/sevenyuan/archive/2010/12/10/1901769.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/sevenyuan/archive/2010/12/08/1900386.html</id><title type="text">Python几种并发实现方案的性能比较</title><summary type="text">1.  前言偶然看到Erlang vs. Stackless python: a first benchmark，对Erlang和Stackless Python的并发处理性能进行了实验比较，基本结论认为二者有比较相近的性能。我看完产生的问题是，Stackless Python与Python的其他并发实现机制性能又会有多大区别呢，比如线程和进程。因此我采用与这篇文章相同的办法来对Stackless Python、普通Python的thread模块、普通Python的threading模块、普通Python的processing模块这四种并发实现方案进行了性能实验，并将实验过程和基本结果记录在这</summary><published>2010-12-08T08:37:00Z</published><updated>2010-12-08T08:37:00Z</updated><author><name>Seven_Yuan</name><uri>http://www.cnblogs.com/sevenyuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/08/1900386.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/08/1900386.html"/><content type="html">&lt;h2 style="margin-top: 0px;"&gt;&lt;a id="toc1" name="toc1"&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;pre&gt;&lt;span style="font-size: 12pt;"&gt;转自：http://www.elias.cn/Python/PyConcurrency&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;h2 style="margin-top: 0px;"&gt;1.&amp;ensp; 前言&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;偶然看到&lt;a  rel="nofollow" href="http://muharem.wordpress.com/2007/07/31/erlang-vs-stackless-python-a-first-benchmark/"&gt;Erlang vs. Stackless python: a first benchmark&lt;/a&gt;，对Erlang和Stackless Python的并发处理性能进行了实验比较，基本结论认为二者有比较相近的性能。我看完产生的问题是，Stackless Python与Python的其他并发实现机制性能又会有多大区别呢，比如线程和进程。因此我采用与这篇文章相同的办法来对Stackless Python、普通Python的thread模块、普通Python的threading模块、普通Python的processing模块这四种并发实现方案进行了性能实验，并将实验过程和基本结果记录在这里。 &lt;/p&gt;&#xD;
&lt;p &gt;后来看到了基于greenlet实现的高性能网络框架&lt;a  rel="nofollow" href="http://wiki.secondlife.com/wiki/Eventlet/Documentation"&gt;Eventlet&lt;/a&gt;，因而更新了实验方案，将greenlet也加入了比较，虽然greenlet并非是一种真正意义上的并发处理，而是在单个线程下对程序块进行切换轮流执行。 &lt;/p&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_2"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h2 style="margin-top: 0px;"&gt;&lt;a id="toc2" name="toc2"&gt;&lt;/a&gt;2.&amp;ensp; 实验方案&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;实验方案与&lt;a  rel="nofollow" href="http://muharem.wordpress.com/2007/07/31/erlang-vs-stackless-python-a-first-benchmark/"&gt;Erlang vs. Stackless python: a first benchmark&lt;/a&gt;是相同的，用每种方案分别给出如下问题的实现，记录完成整个处理过程的总时间来作为评判性能的依据： &lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
&lt;li&gt;由n个节点组成一个环状网络，在上面传送共m个消息。 &lt;/li&gt;&#xD;
&lt;li&gt;将每个消息（共m个），逐个发送给1号节点。 &lt;/li&gt;&#xD;
&lt;li&gt;第1到n-1号节点在接收到消息后，都转发给下一号节点。 &lt;/li&gt;&#xD;
&lt;li&gt;第n号节点每次收到消息后，不再继续转发。 &lt;/li&gt;&#xD;
&lt;li&gt;当m个消息都从1号逐个到达第n号节点时，认为全部处理结束。 &lt;/li&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_3"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h3 style="margin-top: 0px;"&gt;&lt;a id="toc3" name="toc3"&gt;&lt;/a&gt;2.1&amp;ensp; 硬件平台&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Macbook Pro 3,1上的Vmware Fusion 1.0虚拟机中，注意这里给虚拟机只启用了cpu的单个核心： &lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;原始Cpu：Core 2 Duo，2.4 &lt;span &gt;GHz&lt;/span&gt;，2核心，4 MB L2 缓存，总线速度800 &lt;span &gt;MHz&lt;/span&gt; &lt;/li&gt;&#xD;
&lt;li&gt;分配给虚拟机的内存：796M &lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_4"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h3 style="margin-top: 0px;"&gt;&lt;a id="toc4" name="toc4"&gt;&lt;/a&gt;2.2&amp;ensp; 软件平台&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Vmware Fusion 1.0下的Debian etch： &lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;原始Python：Debian发行版自带Python 2.4.4 &lt;/li&gt;&#xD;
&lt;li&gt;Python 2.4.4 Stackless 3.1b3 060516 &lt;/li&gt;&#xD;
&lt;li&gt;processing-0.52-py2.4-linux-i686.egg &lt;/li&gt;&#xD;
&lt;li&gt;原始Python下的greenlet实现：&lt;a  rel="nofollow" href="http://codespeak.net/py/dist/index.html"&gt;py lib 0.9.2&lt;/a&gt; &lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_5"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h2 style="margin-top: 0px;"&gt;&lt;a id="toc5" name="toc5"&gt;&lt;/a&gt;3.&amp;ensp; 实验过程及结果&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;各方案的实现代码见&lt;a href="#Code"&gt;后文&lt;/a&gt;。实验时使用time指令记录每次运行的总时间，选用的都是不做任何输出的no_io实现（Python的print指令还是挺耗资源的，如果不注释掉十有八九得影响测试结果），每次执行时设定n=300，m=10000（&lt;a  rel="nofollow" href="http://muharem.wordpress.com/2007/07/31/erlang-vs-stackless-python-a-first-benchmark/"&gt;Erlang vs. Stackless python: a first benchmark&lt;/a&gt;文章中认为n可以设置为300，m则可以取10000到90000之间的数值分别进行测试）。 &lt;/p&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_6"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h3 style="margin-top: 0px;"&gt;&lt;a id="toc6" name="toc6"&gt;&lt;/a&gt;3.1&amp;ensp; Stackless Python的实验结果&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div style="border: 2px dotted blue; background-color: #eeeeff;"&gt;&#xD;
&lt;pre &gt;real0m1.651s&lt;br /&gt;user0m1.628s&lt;br /&gt;sys0m0.020s&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p &gt;即使将m扩大到30000，实验结果仍然很突出： &lt;/p&gt;&#xD;
&lt;div style="border: 2px dotted blue; background-color: #eeeeff;"&gt;&#xD;
&lt;pre &gt;real0m4.749s&lt;br /&gt;user0m4.716s&lt;br /&gt;sys0m0.028s&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_7"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h3 style="margin-top: 0px;"&gt;&lt;a id="toc7" name="toc7"&gt;&lt;/a&gt;3.2&amp;ensp; 使用thread模块的实验结果&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div style="border: 2px dotted blue; background-color: #eeeeff;"&gt;&#xD;
&lt;pre &gt;real1m13.009s&lt;br /&gt;user0m2.476s&lt;br /&gt;sys0m59.028s&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_8"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h3 style="margin-top: 0px;"&gt;&lt;a id="toc8" name="toc8"&gt;&lt;/a&gt;3.3&amp;ensp; 使用threading模块配合Queue模块的实验结果&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;不太稳定，有时候这样： &lt;/p&gt;&#xD;
&lt;div style="border: 2px dotted blue; background-color: #eeeeff;"&gt;&#xD;
&lt;pre &gt;real1m9.222s&lt;br /&gt;user0m34.418s&lt;br /&gt;sys0m34.622s&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p &gt;也有时这样： &lt;/p&gt;&#xD;
&lt;div style="border: 2px dotted blue; background-color: #eeeeff;"&gt;&#xD;
&lt;pre &gt;real2m14.016s&lt;br /&gt;user0m6.644s&lt;br /&gt;sys2m7.260s&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_9"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h3 style="margin-top: 0px;"&gt;&lt;a id="toc9" name="toc9"&gt;&lt;/a&gt;3.4&amp;ensp; 使用processing模块配合Queue模块的实验结果&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div style="border: 2px dotted blue; background-color: #eeeeff;"&gt;&#xD;
&lt;pre &gt;real3m43.539s&lt;br /&gt;user0m15.345s&lt;br /&gt;sys3m27.953s&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_10"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h3 style="margin-top: 0px;"&gt;&lt;a id="toc10" name="toc10"&gt;&lt;/a&gt;3.5&amp;ensp; greenlet模块的实验结果&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div style="border: 2px dotted blue; background-color: #eeeeff;"&gt;&#xD;
&lt;pre &gt;real0m9.225s&lt;br /&gt;user0m0.644s&lt;br /&gt;sys0m8.581s&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_11"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h3 style="margin-top: 0px;"&gt;&lt;a id="toc11" name="toc11"&gt;&lt;/a&gt;3.6&amp;ensp; eventlet模块的实验结果&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;注意！eventlet 的这个实验结果是后来增补的，硬件平台没变，但是是直接在 OSX 自带 Python 2.5 环境下执行出来的，同时系统中还有 Firefox 等很多程序也在争夺系统资源。因此只能作为大致参考，不能与其他几组数据作直接对比。（其中 eventlet 的版本是 0.9.5） &lt;/p&gt;&#xD;
&lt;div style="border: 2px dotted blue; background-color: #eeeeff;"&gt;&#xD;
&lt;pre &gt;real    0m21.610s&lt;br /&gt;user    0m20.713s&lt;br /&gt;sys     0m0.215s&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_12"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h2 style="margin-top: 0px;"&gt;&lt;a id="toc12" name="toc12"&gt;&lt;/a&gt;4.&amp;ensp; 结论与分析&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_13"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h3 style="margin-top: 0px;"&gt;&lt;a id="toc13" name="toc13"&gt;&lt;/a&gt;4.1&amp;ensp; Stackless Python&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;毫无疑问，Stackless Python几乎有匪夷所思的并发性能，比其他方案快上几十倍，而且借助Stackless Python提供的channel机制，实现也相当简单。也许这个结果向我们部分揭示了沈仙人基于Stackless Python实现的&lt;a  rel="nofollow" href="http://code.google.com/p/eurasia/"&gt;Eurasia3&lt;/a&gt;能够提供相当于c语言效果的恐怖并发性能的原因。 &lt;/p&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_14"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h3 style="margin-top: 0px;"&gt;&lt;a id="toc14" name="toc14"&gt;&lt;/a&gt;4.2&amp;ensp; Python线程&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;从道理上来讲，thread模块似乎应该和threading提供基本相同的性能，毕竟threading只是对thread的一种封装嘛，后台机制应该是一致的。或许threading由于本身类实例维护方面的开销，应该会比直接用thread慢一点。从实验结果来看，二者性能也确实差不多。只是不大明白为何threading方案的测试结果不是很稳定，即使对其他方案的测试运行多次，误差也不会像threading这么飘。从代码实现体验来说，用threading配合Queue比直接用thread实在是轻松太多了，并且出错的机会也要少很多。 &lt;/p&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_15"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h3 style="margin-top: 0px;"&gt;&lt;a id="toc15" name="toc15"&gt;&lt;/a&gt;4.3&amp;ensp; Python进程&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;processing模块给出的进程方案大致比thread线程要慢一倍，并且这是在我特意调整虚拟机给它预备了足够空闲内存、避免使用交换分区的情况下取得的（特意分给虚拟机700多M内存就是为了这个）。而其他方案仅仅占用数M内存，完全无需特意调大可用内存总量。当然，如果给虚拟机多启用几个核心的话，processing也许会占上点便宜，毕竟目前thread模块是不能有效利用多cpu资源的（经实验，Stackless Python在开启双核的情况下表现的性能和单核是一样的，说明也是不能有效利用多cpu）。因此一种比较合理的做法是根据cpu的数量，启用少量几个进程，而在进程内部再开启线程进行实际业务处理，这也是目前Python社区推荐的有效利用多cpu资源的办法。好在processing配合其自身提供的Queue模块，编程体验还是比较轻松的。 &lt;/p&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_16"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h3 style="margin-top: 0px;"&gt;&lt;a id="toc16" name="toc16"&gt;&lt;/a&gt;4.4&amp;ensp; greenlet超轻量级方案&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;基于greenlet的实现则性能仅次于Stackless Python，大致比Stackless Python慢一倍，比其他方案快接近一个数量级。其实greenlet不是一种真正的并发机制，而是在同一线程内，在不同函数的执行代码块之间切换，实施&amp;ldquo;你运行一会、我运行一会&amp;rdquo;，并且在进行切换时必须指定何时切换以及切换到哪。greenlet的接口是比较简单易用的，但是使用greenlet时的思考方式与其他并发方案存在一定区别。线程/进程模型在大逻辑上通常从并发角度开始考虑，把能够并行处理的并且值得并行处理的任务分离出来，在不同的线程/进程下运行，然后考虑分离过程可能造成哪些互斥、冲突问题，将互斥的资源加锁保护来保证并发处理的正确性。greenlet则是要求从避免阻塞的角度来进行开发，当出现阻塞时，就显式切换到另一段没有被阻塞的代码段执行，直到原先的阻塞状况消失以后，再人工切换回原来的代码段继续处理。因此，greenlet本质是一种合理安排了的串行，实验中greenlet方案能够得到比较好的性能表现，主要也是因为通过合理的代码执行流程切换，完全避免了死锁和阻塞等情况（执行带屏幕输出的ring_greenlet.py我们会看到脚本总是一个一个地处理消息，把一个消息在环上从头传到尾之后，再开始处理下一个消息）。因为greenlet本质是串行，因此在没有进行显式切换时，代码的其他部分是无法被执行到的，如果要避免代码长时间占用运算资源造成程序假死，那么还是要将greenlet与线程/进程机制结合使用（每个线程、进程下都可以建立多个greenlet，但是跨线程/进程时greenlet之间无法切换或通讯）。 &lt;/p&gt;&#xD;
&lt;p &gt;Stackless则比较特别，对很多资源从底层进行了并发改造，并且提供了channel等更适合&amp;ldquo;并发&amp;rdquo;的通讯机制实现，使得资源互斥冲突的可能性大大减小，并发性能自然得以提高。粗糙来讲，greenlet是&amp;ldquo;阻塞了我就先干点儿别的，但是程序员得明确告诉greenlet能先干点儿啥以及什么时候回来&amp;rdquo;；Stackless则是&amp;ldquo;东西我已经改造好了，你只要用我的东西，并发冲突就不用操心，只管放心大胆地并发好了&amp;rdquo;。greenlet应该是学习了Stackless的上下文切换机制，但是对底层资源没有进行适合并发的改造。并且实际上greenlet也没有必要改造底层资源的并发性，因为它本质是串行的单线程，不与其他并发模型混合使用的话是无法造成对资源的并发访问的。 &lt;/p&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_17"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h4 style="margin-top: 0px;"&gt;greenlet 封装后的 eventlet 方案&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;eventlet 是基于 greenlet 实现的面向网络应用的并发处理框架，提供&amp;ldquo;线程&amp;rdquo;池、队列等与其他 Python 线程、进程模型非常相似的 api，并且提供了对 Python 发行版自带库及其他模块的超轻量并发适应性调整方法，比直接使用 greenlet 要方便得多。并且这个解决方案源自著名虚拟现实游戏&amp;ldquo;第二人生&amp;rdquo;，可以说是久经考验的新兴并发处理模型。其基本原理是调整 Python 的 socket 调用，当发生阻塞时则切换到其他 greenlet 执行，这样来保证资源的有效利用。需要注意的是： &lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;eventlet 提供的函数只能对 Python 代码中的 socket 调用进行处理，而不能对模块的 C 语言部分的 socket 调用进行修改。对后者这类模块，仍然需要把调用模块的代码封装在 Python 标准线程调用中，之后利用 eventlet 提供的适配器实现 eventlet 与标准线程之间的协作。 &lt;/li&gt;&#xD;
&lt;li&gt;再有，虽然 eventlet 把 api 封装成了非常类似标准线程库的形式，但两者的实际并发执行流程仍然有明显区别。在没有出现 I/O 阻塞时，除非显式声明，否则当前正在执行的 eventlet 永远不会把 cpu 交给其他的 eventlet，而标准线程则是无论是否出现阻塞，总是由所有线程一起争夺运行资源。所有 eventlet 对 I/O 阻塞无关的大运算量耗时操作基本没有什么帮助。 &lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p &gt;在性能测试结果方面，eventlet 消耗的运行时间大致是 greenlet 方案的 3 到 5 倍，而 Python 标准线程模型的 thread 方式消耗的运行时间大致是 eventlet 测试代码的 8 到 10 倍。其中前者可能是因为我们在 eventlet 的测试代码中，使用队列机制来完成所有的消息传递，而队列上的访问互斥保护可能额外消耗了一些运算资源。总体而言，eventlet 模型的并发性能虽然比 Stackless Python 和直接使用 greenlet 有一定差距，但仍然比标准线程模型有大约一个数量级的优势，这也就不奇怪近期很多强调并发性能的网络服务器实现采取 eventlet 、线程、进程三者组合使用的实现方案。 &lt;/p&gt;&#xD;
&lt;div &gt;&lt;a name="sPython.PyConcurrency_18"&gt;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;h2 style="margin-top: 0px;"&gt;&lt;a id="toc17" name="toc17"&gt;&lt;/a&gt;5.&amp;ensp; 实验代码&lt;a id="Code" name="Code"&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;实验代码下载： &lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&lt;a  rel="nofollow" href="http://www.elias.cn/uploads/Develop/py_concurrency_v3.tar"&gt;版本3 下载&lt;/a&gt;：增加了 eventlet 方案的实验代码。 &lt;/li&gt;&#xD;
&lt;li&gt;&lt;a  rel="nofollow" href="http://www.elias.cn/uploads/Develop/py_concurrency_v2.tar"&gt;版本2 下载&lt;/a&gt;：增加了 greenlet 方案的实验代码。 &lt;/li&gt;&#xD;
&lt;li&gt;&lt;a  rel="nofollow" href="http://www.elias.cn/uploads/Develop/py_concurrency.tar"&gt;版本1 下载&lt;/a&gt;：包括 Stackless Python 、 thread 、 threading 、 processing 四种方案的实验代码。 &lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p &gt;为方便阅读，将实验中用到的几个脚本的代码粘贴如下，其中Stackless Python方案的代码实现直接取自&lt;a  rel="nofollow" href="http://muharem.wordpress.com/2007/07/31/erlang-vs-stackless-python-a-first-benchmark/"&gt;Erlang vs. Stackless python: a first benchmark&lt;/a&gt;：&lt;/p&gt;&#xD;
&lt;p &gt;5.1&amp;ensp; ring_no_io_slp.py&lt;/p&gt;&#xD;
&lt;p &gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('154b5da4-40b6-403e-8050-15971200fe25')"&gt;&#xD;
&lt;div id="cnblogs_code_open_154b5da4-40b6-403e-8050-15971200fe25" &gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;!/Library/Frameworks/Python.framework/Versions/2.5/bin/python&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; encoding: utf-8&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; sys&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; stackless as SL&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; run_benchmark(n, m):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("&amp;gt;&amp;gt; Python 2.5.1, stackless 3.1b3 here (N=%d, M=%d)!\n" % (n, m))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    firstP &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SL.channel()&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; s &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; xrange(&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, n):&lt;br /&gt;        seqn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;br /&gt;        cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SL.channel()&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; # print("*&amp;gt; s = %d" % (seqn, ))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        t &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SL.tasklet(loop)(seqn, cin, cout)&lt;br /&gt;        cin &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cout&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;        seqn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; # print("$&amp;gt; s = %d" % (seqn, ))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        t &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SL.tasklet(mloop)(seqn, cin)&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; xrange(m&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;):&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; # print("+ sending Msg#  %d" % r)&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        firstP.send(r)&lt;br /&gt;    SL.schedule()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; loop(s, cin, cout):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; True:&lt;br /&gt;        r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin.receive()&lt;br /&gt;        cout.send(r)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0: &lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print(": Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: %s .." % (pid(), s, r))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;pass&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("* Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: terminate!" % (pid(), s))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; mloop(s, cin):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; True:&lt;br /&gt;        r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin.receive()&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0: &lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("&amp;gt; Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: %s .." % (pid(), s, r))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;pass&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("@ Proc: &amp;lt;%s&amp;gt;, Seq#: %s, ring terminated." % (pid(), s))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; pid(): &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; repr(SL.getcurrent()).split()[&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;][&lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__name__&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;__main__&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;    run_benchmark(int(sys.argv[&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]), int(sys.argv[&lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;]))&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
5.2&amp;ensp; ring_no_io_thread.py&lt;/p&gt;&#xD;
&lt;p &gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('03a5bbc5-0fc9-4f65-901d-26bbe5737f0f')"&gt;&#xD;
&lt;div id="cnblogs_code_open_03a5bbc5-0fc9-4f65-901d-26bbe5737f0f" &gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;!/Library/Frameworks/Python.framework/Versions/2.5/bin/python&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; encoding: utf-8&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; sys, time&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; thread&lt;br /&gt; &lt;br /&gt;SLEEP_TIME &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;0.0001&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; run_benchmark(n, m):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("&amp;gt;&amp;gt; Python 2.5.1, stackless 3.1b3 here (N=%d, M=%d)!\n" % (n, m))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    locks &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; [thread.allocate_lock() &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; xrange(n)]&lt;br /&gt;    firstP &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; []&lt;br /&gt;    cin_lock_id &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; s &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; xrange(&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, n):&lt;br /&gt;        seqn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;br /&gt;        cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; []&lt;br /&gt;        cout_lock_id &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("*&amp;gt; s = %d" % (seqn, ))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        thread.start_new_thread(loop, (seqn, locks, cin, cin_lock_id, cout, cout_lock_id))&lt;br /&gt;        cin &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cout&lt;br /&gt;        cin_lock_id &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cout_lock_id&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;        seqn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("$&amp;gt; s = %d" % (seqn, ))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        thread.start_new_thread(mloop, (seqn, locks, cin, cin_lock_id))&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; xrange(m&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;):&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("+ sending Msg#  %d" % r)&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        lock &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; locks[0]&lt;br /&gt;        lock.acquire()&lt;br /&gt;        firstP.append(r)&lt;br /&gt;        lock.release()&lt;br /&gt;        time.sleep(SLEEP_TIME)&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; True:&lt;br /&gt;            time.sleep(SLEEP_TIME)&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;except&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;pass&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; loop(s, locks, cin, cin_lock_id, cout, cout_lock_id):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; True:&lt;br /&gt;        lock &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; locks[cin_lock_id]&lt;br /&gt;        lock.acquire()&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; len(cin) &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0:&lt;br /&gt;            r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin.pop(0)&lt;br /&gt;            lock.release()&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            lock.release()&lt;br /&gt;            time.sleep(SLEEP_TIME)&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;continue&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        lock &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; locks[cout_lock_id]&lt;br /&gt;        lock.acquire()&lt;br /&gt;        cout.append(r)&lt;br /&gt;        lock.release()&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0: &lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print(": Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: %s .." % (pid(), s, r))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;pass&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("* Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: terminate!" % (pid(), s))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; mloop(s, locks, cin, cin_lock_id):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; True:&lt;br /&gt;        lock &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; locks[cin_lock_id]&lt;br /&gt;        lock.acquire()&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; len(cin) &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0:&lt;br /&gt;            r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin.pop(0)&lt;br /&gt;            lock.release()&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            lock.release()&lt;br /&gt;            time.sleep(SLEEP_TIME)&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;continue&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0: &lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("&amp;gt; Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: %s .." % (pid(), s, r))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;pass&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("@ Proc: &amp;lt;%s&amp;gt;, Seq#: %s, ring terminated." % (pid(), s))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;    thread.interrupt_main()&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; pid(): &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; thread.get_ident()&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__name__&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;__main__&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;    run_benchmark(int(sys.argv[&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]), int(sys.argv[&lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;]))&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
5.3&amp;ensp; ring_no_io_queue.py&lt;/p&gt;&#xD;
&lt;p &gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('1d8a77cf-76f8-4c34-a1bd-d24f1bb8a010')"&gt;&#xD;
&lt;div id="cnblogs_code_open_1d8a77cf-76f8-4c34-a1bd-d24f1bb8a010" &gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;!/Library/Frameworks/Python.framework/Versions/2.5/bin/python&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; encoding: utf-8&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; sys&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; threading, Queue&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; run_benchmark(n, m):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("&amp;gt;&amp;gt; Python 2.5.1, stackless 3.1b3 here (N=%d, M=%d)!\n" % (n, m))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    firstP &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Queue.Queue()&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; s &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; xrange(&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, n):&lt;br /&gt;        seqn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;br /&gt;        cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Queue.Queue()&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("*&amp;gt; s = %d" % (seqn, ))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        t &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Loop(seqn, cin, cout)&lt;br /&gt;        t.setDaemon(False)&lt;br /&gt;        t.start()&lt;br /&gt;        cin &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cout&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;        seqn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("$&amp;gt; s = %d" % (seqn, ))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        t &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; MLoop(seqn, cin)&lt;br /&gt;        t.setDaemon(False)&lt;br /&gt;        t.start()&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; xrange(m&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;):&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("+ sending Msg#  %d" % r)&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        firstP.put(r)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Loop(threading.Thread):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self, s, cin, cout):&lt;br /&gt;        threading.Thread.&lt;/span&gt;&lt;span style="color: #800080;"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self)&lt;br /&gt;        self.cin &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin&lt;br /&gt;        self.cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cout&lt;br /&gt;        self.s &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; run(self):&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; True:&lt;br /&gt;            r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; self.cin.get()&lt;br /&gt;            self.cout.put(r)&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0: &lt;br /&gt;                 &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print(": Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: %s .." % (pid(), self.s, r))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;                 &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;pass&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                 &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("* Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: terminate!" % (pid(), self.s))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;                 &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; MLoop(threading.Thread):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self, s, cin):&lt;br /&gt;        threading.Thread.&lt;/span&gt;&lt;span style="color: #800080;"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self)&lt;br /&gt;        self.cin &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin&lt;br /&gt;        self.s &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; run(self):&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; True:&lt;br /&gt;            r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; self.cin.get()&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0: &lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("&amp;gt; Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: %s .." % (pid(), self.s, r))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;pass&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("@ Proc: &amp;lt;%s&amp;gt;, Seq#: %s, ring terminated." % (pid(), self.s))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; pid(): &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; threading.currentThread()&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__name__&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;__main__&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;    run_benchmark(int(sys.argv[&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]), int(sys.argv[&lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;]))&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
5.4&amp;ensp; ring_no_io_proc.py&lt;/p&gt;&#xD;
&lt;p &gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('3febda53-86ac-4bdb-829f-e6788fae8573')"&gt;&#xD;
&lt;div id="cnblogs_code_open_3febda53-86ac-4bdb-829f-e6788fae8573" &gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;!/Library/Frameworks/Python.framework/Versions/2.5/bin/python&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; encoding: utf-8&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; sys&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; processing, Queue&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; run_benchmark(n, m):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("&amp;gt;&amp;gt; Python 2.5.1, stackless 3.1b3 here (N=%d, M=%d)!\n" % (n, m))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    firstP &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; processing.Queue()&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; s &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; xrange(&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, n):&lt;br /&gt;        seqn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;br /&gt;        cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; processing.Queue()&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("*&amp;gt; s = %d" % (seqn, ))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; processing.Process(target &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; loop, args &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; [seqn, cin, cout])&lt;br /&gt;        p.start()&lt;br /&gt;        cin &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cout&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;        seqn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("$&amp;gt; s = %d" % (seqn, ))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; processing.Process(target &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; mloop, args &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; [seqn, cin])&lt;br /&gt;        p.start()&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; xrange(m&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;):&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("+ sending Msg#  %d" % r)&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        firstP.put(r)&lt;br /&gt;    p.join()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; loop(s, cin, cout):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; True:&lt;br /&gt;        r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin.get()&lt;br /&gt;        cout.put(r)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0: &lt;br /&gt;             &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print(": Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: %s .." % (pid(), s, r))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;             &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;pass&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;             &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("* Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: terminate!" % (pid(), s))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;             &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; mloop(s, cin):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; True:&lt;br /&gt;        r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin.get()&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0: &lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("&amp;gt; Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: %s .." % (pid(), s, r))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;pass&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("@ Proc: &amp;lt;%s&amp;gt;, Seq#: %s, ring terminated." % (pid(), s))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; pid(): &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; processing.currentProcess()&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__name__&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;__main__&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;    run_benchmark(int(sys.argv[&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]), int(sys.argv[&lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;]))&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
5.5&amp;ensp; ring_no_io_greenlet.py&lt;/p&gt;&#xD;
&lt;p &gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('929d57d7-ecc8-46d8-9ce7-82c3696ad02c')"&gt;&#xD;
&lt;div id="cnblogs_code_open_929d57d7-ecc8-46d8-9ce7-82c3696ad02c" &gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;!/Library/Frameworks/Python.framework/Versions/2.5/bin/python&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; encoding: utf-8&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; sys&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;from&lt;/span&gt;&lt;span style="color: #000000;"&gt; py.magic &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; greenlet&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; run_benchmark(n, m):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("&amp;gt;&amp;gt; Python 2.5.1, stackless 3.1b3 here (N=%d, M=%d)!\n" % (n, m))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    glets &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; [greenlet.getcurrent()]&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; s &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; xrange(&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, n):&lt;br /&gt;        seqn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;br /&gt;        glets.append(greenlet(loop))&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("*&amp;gt; s = %d" % (seqn, ))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;        seqn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        glets.append(greenlet(mloop))&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("$&amp;gt; s = %d" % (seqn, ))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    glets[&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;].switch(seqn, glets)&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; xrange(m&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;):&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("+ sending Msg#  %d" % r)&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        glets[&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;].switch(r)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; loop(s, glets):&lt;br /&gt;    previous &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; glets[s &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]&lt;br /&gt;    next &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; glets[s &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; s &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;        r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; previous.switch(s &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, glets)&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;        r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; previous.switch()&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; True:&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0: &lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print(": Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: %s .." % (pid("loop", s), s, r))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;pass&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("* Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: terminate!" % (pid("loop", s), s))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        next.switch(r)&lt;br /&gt;        r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; previous.switch()&lt;br /&gt;    next.switch(r)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; mloop(s, glets):&lt;br /&gt;    previous &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; glets[s &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]&lt;br /&gt;    r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; previous.switch(s &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, glets)&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; True:&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0: &lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("&amp;gt; Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: %s .." % (pid("mloop", s), s, r))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;pass&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("@ Proc: &amp;lt;%s&amp;gt;, Seq#: %s, ring terminated." % (pid("mloop", s), s))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; previous.switch()&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; pid(func, s): &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;lt;&amp;lt;%s(Greenlet-%d, started)&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;%&lt;/span&gt;&lt;span style="color: #000000;"&gt; (func, s)&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__name__&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;__main__&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;    run_benchmark(int(sys.argv[&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]), int(sys.argv[&lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;]))&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
5.6&amp;ensp; ring_no_io_eventlet.py&lt;/p&gt;&#xD;
&lt;p &gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('2ea713c6-c50f-478d-b598-2395a82c3ed2')"&gt;&#xD;
&lt;div id="cnblogs_code_open_2ea713c6-c50f-478d-b598-2395a82c3ed2" &gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;!/Library/Frameworks/Python.framework/Versions/2.5/bin/python&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; encoding: utf-8&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; sys&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; eventlet&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; run_benchmark(n, m):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("&amp;gt;&amp;gt; Python 2.5.1, stackless 3.1b3 here (N=%d, M=%d)!\n" % (n, m))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    firstP &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; eventlet.Queue()&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; s &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; xrange(&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, n):&lt;br /&gt;        seqn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;br /&gt;        cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; eventlet.Queue()&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("*&amp;gt; s = %d" % (seqn, ))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        eventlet.spawn_n(loop, seqn, cin, cout)&lt;br /&gt;        cin &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cout&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;        seqn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("$&amp;gt; s = %d" % (seqn, ))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; xrange(m&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;):&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("+ sending Msg#  %d" % r)&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        firstP.put(r)&lt;br /&gt;    mloop(seqn, cin)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; loop(s, cin, cout):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; True:&lt;br /&gt;        r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin.get()&lt;br /&gt;        cout.put(r)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0: &lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print(": Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: %s .." % (pid(), s, r))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;pass&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("* Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: terminate!" % (pid(), s))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; mloop(s, cin):&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; True:&lt;br /&gt;        r &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; cin.get()&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; r &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 0: &lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("&amp;gt; Proc: &amp;lt;%s&amp;gt;, Seq#: %s, Msg#: %s .." % (pid(), s, r))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;pass&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; print("@ Proc: &amp;lt;%s&amp;gt;, Seq#: %s, ring terminated." % (pid(), s))&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; pid(): &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; eventlet.greenthread.getcurrent()&lt;br /&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__name__&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;__main__&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;    run_benchmark(int(sys.argv[&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]), int(sys.argv[&lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;]))&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;/p&gt;&lt;img src="http://www.cnblogs.com/sevenyuan/aggbug/1900386.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/sevenyuan/archive/2010/12/08/1900386.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898366.html</id><title type="text">用struct模块处理二进制数据</title><summary type="text">有的时候需要用python处理二进制数据，比如，存取文件，socket操作时.这时候，可以使用python的struct模块来完成.可以用struct来处理c语言中的结构体.struct模块中最重要的三个函数是pack(), unpack(), calcsize()pack(fmt, v1, v2, ...) 按照给定的格式(fmt)，把数据封装成字符串(实际上是类似于c结构体的字节流)unpack(fmt, string) 按照给定的格式(fmt)解析字节流string，返回解析出来的tuplecalcsize(fmt) 计算给定的格式(fmt)占用多少字节的内存struct中支持的格式如下</summary><published>2010-12-06T14:43:00Z</published><updated>2010-12-06T14:43:00Z</updated><author><name>Seven_Yuan</name><uri>http://www.cnblogs.com/sevenyuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898366.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898366.html"/><content type="html">&lt;p&gt;有的时候需要用python处理二进制数据，比如，存取文件，socket操作时.这时候，可以使用python的struct模块来完成.可以用struct来处理c语言中的结构体.&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;struct模块中最重要的三个函数是pack(), unpack(), calcsize()&lt;/p&gt;&#xD;
&lt;p&gt;pack(fmt, v1, v2, ...)&amp;nbsp;&amp;nbsp;&amp;nbsp; 按照给定的格式(fmt)，把数据封装成字符串(实际上是类似于c结构体的字节流)&lt;br /&gt;unpack(fmt, string)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 按照给定的格式(fmt)解析字节流string，返回解析出来的tuple&lt;br /&gt;calcsize(fmt)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 计算给定的格式(fmt)占用多少字节的内存&lt;br /&gt;struct中支持的格式如下表：&lt;/p&gt;&#xD;
&lt;p&gt;&amp;gt; 格式 c类型 python类型 &lt;br /&gt;&amp;gt; x char 无(表示填充字节) &lt;br /&gt;&amp;gt; c char 长度为1的字符串 &lt;br /&gt;&amp;gt; b signed char integer &lt;br /&gt;&amp;gt; B unsigned char integer &lt;br /&gt;&amp;gt; h short integer &lt;br /&gt;&amp;gt; H unsigned short integer &lt;br /&gt;&amp;gt; i int integer &lt;br /&gt;&amp;gt; I unsigned int long &lt;br /&gt;&amp;gt; l long integer &lt;br /&gt;&amp;gt; L unsigned long long &lt;br /&gt;&amp;gt; q long long long &lt;br /&gt;&amp;gt; Q unsigned long long long &lt;br /&gt;&amp;gt; f float float &lt;br /&gt;&amp;gt; d double float &lt;br /&gt;&amp;gt; s char[] string &lt;br /&gt;&amp;gt; p char[] string &lt;br /&gt;&amp;gt; P void* integer &lt;/p&gt;&#xD;
&lt;p&gt;注1.q和Q只在机器支持64位操作时有意思&lt;br /&gt;注2.每个格式前可以有一个数字，表示个数&lt;br /&gt;注3.s格式表示一定长度的字符串，4s表示长度为4的字符串，但是p表示的是pascal字符串&lt;br /&gt;注4.P用来转换一个指针，其长度和机器字长相关&lt;/p&gt;&#xD;
&lt;p&gt;默认情况下struct根据本地机器字节顺序转换.不过可以用格式中的第一个字符来改变对齐方式.定义如下：&lt;/p&gt;&#xD;
&lt;p&gt;&amp;gt; 字符 字节顺序 长度和对齐方式 &lt;br /&gt;&amp;gt; @ native native &lt;br /&gt;&amp;gt; = native standard &lt;br /&gt;&amp;gt; &amp;lt; little-endian standard &lt;br /&gt;&amp;gt; &amp;gt; big-endian standard &lt;br /&gt;&amp;gt; ! network (= big-endian) standard &lt;/p&gt;&#xD;
&lt;p&gt;有了struct，我们就可以很容易操作二进制数据了.&lt;/p&gt;&#xD;
&lt;p&gt;比如有一个结构体:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #000000;"&gt;struct Header&lt;br /&gt;{&lt;br /&gt;    unsigned short id;&lt;br /&gt;    char[&lt;/span&gt;&lt;span style="color: #000000;"&gt;4&lt;/span&gt;&lt;span style="color: #000000;"&gt;] tag;&lt;br /&gt;    unsigned int version;&lt;br /&gt;    unsigned int count;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
通过socket.recv接收到了一个上面的结构体数据，存在字符串s中，现在需要把它解析出来，可以使用unpack()函数.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; struct&lt;br /&gt;id, tag, version, count &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; struct.unpack(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;!H4s2I&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, s)&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;上面的格式字符串中，!表示我们要使用网络字节顺序解析，因为我们的数据是从网络中接收到的，在网络上传送的时候它是网络字节顺序的.后面的H表示一个unsigned short的id,4s表示4字节长的字符串，2I表示有两个unsigned int类型的数据.&lt;/p&gt;&#xD;
&lt;p&gt;就通过一个unpack，现在id, tag, version, count里已经保存好我们的信息了.&lt;/p&gt;&#xD;
&lt;p&gt;同样，也可以很方便的把本地数据再pack成struct格式.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #000000;"&gt;ss &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; struct.pack(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;!H4s2I&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, id, tag, version, count);&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
pack函数就把id, tag, version, count按照指定的格式转换成了结构体Header，ss现在是一个字符串(实际上是类似于c结构体的字节流)，可以通过socket.send(ss)把这个字符串发送出去.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;转自：http://blog.csdn.net/meteor1113/archive/2009/07/15/4350252.aspx&lt;/p&gt;&lt;img src="http://www.cnblogs.com/sevenyuan/aggbug/1898366.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898366.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898081.html</id><title type="text">理解Python命名机制</title><summary type="text">代码初探正确的答案是：[代码]如果您已经猜对了，那么可以不看我这篇博文了。如果你没有猜对或者心里有所疑问，那我的这篇博文正是为您所准备的。一切由为什么会输出“A.__private()”开始。但要讲清楚为什么，我们就有必要了解一下Python的命名机制。据 Python manual，变量名（标识符）是Python的一种原子元素。当变量名被绑定到一个对象的时候，变量名就指代这个对象，就像人类社会一样，不是吗？当变量名出现在代码块中，那它就是本地变量；当变量名出现在模块中，它就是全局变量。模块相信大家都有很好的理解，但代码块可能让人费解些。在这里解释一下：代码块就是可作为可执行单元的一段Pyth</summary><published>2010-12-06T12:10:00Z</published><updated>2010-12-06T12:10:00Z</updated><author><name>Seven_Yuan</name><uri>http://www.cnblogs.com/sevenyuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898081.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898081.html"/><content type="html">&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('34344c83-eb9f-47e4-8220-c1caf2b71d16')"&gt;&#xD;
&lt;div id="cnblogs_code_open_34344c83-eb9f-47e4-8220-c1caf2b71d16"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; A(object):&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self):&lt;br /&gt;              self.&lt;/span&gt;&lt;span style="color: #800080;"&gt;__private&lt;/span&gt;&lt;span style="color: #000000;"&gt;()&lt;br /&gt;              self.public()&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__private&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self):&lt;br /&gt;              &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;A.__private()&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; public(self):&lt;br /&gt;              &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;A.public()&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; B(A):&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__private&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self):&lt;br /&gt;              &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;B.__private()&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; public(self):&lt;br /&gt;              &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;B.public()&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;b &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; B()&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div&gt;&lt;strong&gt;&lt;span style="font-size: 14pt;"&gt;初探&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="text-indent: 21pt;"&gt;正确的答案是：&lt;br /&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #000000;"&gt;A.&lt;/span&gt;&lt;span style="color: #800080;"&gt;__private&lt;/span&gt;&lt;span style="color: #000000;"&gt;()&lt;br /&gt;B.public()&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
如果您已经猜对了，那么可以不看我这篇博文了。如果你没有猜对或者心里有所疑问，那我的这篇博文正是为您所准备的。&lt;br /&gt;一切由为什么会输出&amp;ldquo;A.__private()&amp;rdquo;开始。但要讲清楚为什么，我们就有必要了解一下Python的命名机制。&lt;br /&gt;据 Python manual，变量名（标识符）是Python的一种原子元素。当变量名被绑定到一个对象的时候，变量名就指代这个对象，就像人类社会一样，不是吗？当变量名出现在代码块中，那它就是本地变量；当变量名出现在模块中，它就是全局变量。模块相信大家都有很好的理解，但代码块可能让人费解些。在这里解释一下：&lt;br /&gt;代码块就是可作为可执行单元的一段Python程序文本；模块、函数体和类定义都是代码块。不仅如此，每一个交互脚本命令也是一个代码块；一个脚本文件也是一个代码块；一个命令行脚本也是一个代码块。&lt;br /&gt;接下来谈谈变量的可见性，我们引入一个范围的概念。范围就是变量名在代码块的可见性。如果一个代码块里定义本地变量，那范围就包括这个代码块。如果变量定义在一个功能代码块里，那范围就扩展到这个功能块里的任一代码块，除非其中定义了同名的另一变量。但定义在类中的变量的范围被限定在类代码块，而不会扩展到方法代码块中。&lt;br /&gt;迷踪&lt;br /&gt;据上节的理论，我们可以把代码分为三个代码块：类A的定义、类B的定义和变量b的定义。根据类定义，我们知道代码给类A定义了三个成员变量（Python的函数也是对象，所以成员方法称为成员变量也行得通。）；类B定义了两个成员变量。这可以通过以下代码验证：&lt;br /&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;.join(dir(A))&lt;br /&gt;_A__private&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;public&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;.join(dir(B))&lt;br /&gt;_A__private&lt;br /&gt;_B__private&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;public&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
咦，为什么类A有个名为_A__private的 Attribute 呢？而且__private消失了！这就要谈谈Python的私有变量轧压了。&lt;br /&gt;探究&lt;br /&gt;懂Python的朋友都知道Python把以两个或以上下划线字符开头且没有以两个或以上下划线结尾的变量当作私有变量。私有变量会在代码生成之前被转换为长格式（变为公有）。转换机制是这样的：在变量前端插入类名，再在前端加入一个下划线字符。这就是所谓的私有变量轧压（Private name mangling）。如类A里的__private标识符将被转换为_A__private，这就是上一节出现_A__private和__private消失的原因了。&lt;br /&gt;再讲两点题外话：&lt;br /&gt;一是因为轧压会使标识符变长，当超过255的时候，Python会切断，要注意因此引起的命名冲突。&lt;br /&gt;二是当类名全部以下划线命名的时候，Python就不再执行轧压。如：&#xD;
&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('c2282f42-501f-4e7f-aed1-2264b5f9781f')"&gt;&#xD;
&lt;div id="cnblogs_code_open_c2282f42-501f-4e7f-aed1-2264b5f9781f" &gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;____&lt;/span&gt;&lt;span style="color: #000000;"&gt;(object):&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self):&lt;br /&gt;              self.&lt;/span&gt;&lt;span style="color: #800080;"&gt;__method&lt;/span&gt;&lt;span style="color: #000000;"&gt;()&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__method&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self):&lt;br /&gt;              &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;____.__method()&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;.join(dir(&lt;/span&gt;&lt;span style="color: #800080;"&gt;____&lt;/span&gt;&lt;span style="color: #000000;"&gt;))&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__class__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__delattr__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__dict__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__doc__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__getattribute__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__hash__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__method&lt;/span&gt;&lt;span style="color: #000000;"&gt;              &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; 没被轧压&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__module__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__new__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__reduce__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__reduce_ex__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__repr__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__setattr__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__str__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;__weakref__&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; obj &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;____&lt;/span&gt;&lt;span style="color: #000000;"&gt;()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;____&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #800080;"&gt;__method&lt;/span&gt;&lt;span style="color: #000000;"&gt;()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; obj.&lt;/span&gt;&lt;span style="color: #800080;"&gt;__method&lt;/span&gt;&lt;span style="color: #000000;"&gt;()      &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; 可以外部调用&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;____&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #800080;"&gt;__method&lt;/span&gt;&lt;span style="color: #000000;"&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
现在我们回过头来看看为什么会输出&amp;ldquo;A.__private()&amp;rdquo;吧！&lt;strong&gt;&lt;span style="font-size: 14pt;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-size: 14pt;"&gt;真相&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;相信现在聪明的读者已经猜到答案了吧？如果你还没有想到，我给你个提示：真相跟C语言里的宏预处理差不多。&lt;/p&gt;&#xD;
&lt;p&gt;因为类A定义了一个私有成员函数（变量），所以在代码生成之前先执行私有变量轧压（注意到上一节标红的那行字没有？）。轧压之后，类A的代码就变成这样了:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('c008defa-dab0-427c-96f9-97e2956c1a6d')"&gt;&#xD;
&lt;div id="cnblogs_code_open_c008defa-dab0-427c-96f9-97e2956c1a6d"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; A(object):&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self):&lt;br /&gt;              self._A__private()          &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; 这行变了&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;              self.public()&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; _A__private(self):           &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; 这行也变了&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;              &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;A.__private()&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; public(self):&lt;br /&gt;              &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;A.public()&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
是不是有点像C语言里的宏展开啊？&lt;/p&gt;&#xD;
&lt;p&gt;因为在类B定义的时候没有覆盖__init__方法，所以调用的仍然是A.__init__，即执行了self._A__private()，自然输出&amp;ldquo;A.__private()&amp;rdquo;了。&lt;/p&gt;&#xD;
&lt;p&gt;下面的两段代码可以增加说服力，增进理解：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('bd585d4d-ceaa-46b4-82c9-e3c7a4ae278f')"&gt;&#xD;
&lt;div id="cnblogs_code_open_bd585d4d-ceaa-46b4-82c9-e3c7a4ae278f" &gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; C(A):&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self):          &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; 重写__init__，不再调用self._A__private&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;              self.&lt;/span&gt;&lt;span style="color: #800080;"&gt;__private&lt;/span&gt;&lt;span style="color: #000000;"&gt;()       &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; 这里绑定的是_C_private&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;              self.public()&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__private&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self):&lt;br /&gt;              &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;C.__private()&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; public(self):&lt;br /&gt;              &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;C.public()&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; c &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; C()&lt;br /&gt;C.&lt;/span&gt;&lt;span style="color: #800080;"&gt;__private&lt;/span&gt;&lt;span style="color: #000000;"&gt;()&lt;br /&gt;C.public()&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;###########################&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; A(object):&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self):&lt;br /&gt;              self._A__private()   &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; 调用一个没有定义的函数，Python会把它给我的 ^_^～&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;              self.public()&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;__private&lt;/span&gt;&lt;span style="color: #000000;"&gt;(self):&lt;br /&gt;              &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;A.__private()&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt; public(self):&lt;br /&gt;              &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;A.public()&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;a &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; A()&lt;br /&gt;A.&lt;/span&gt;&lt;span style="color: #800080;"&gt;__private&lt;/span&gt;&lt;span style="color: #000000;"&gt;()&lt;br /&gt;A.public()&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;转自：http://blog.csdn.net/lanphaday/archive/2007/08/09/1734990.aspx&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/sevenyuan/aggbug/1898081.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898081.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898075.html</id><title type="text">Python中re(正则表达式)模块学习</title><summary type="text">今天学习了Python中有关正则表达式的知识。关于正则表达式的语法，不作过多解释，网上有许多学习的资料。这里主要介绍Python中常用的正则表达式处理函数。re.match　　re.match 尝试从字符串的开始匹配一个模式，如：下面的例子匹配第一个单词。 [代码]re.match的函数原型为：re.match(pattern, string, flags)第一个参数是正则表达式，这里为"(\w+)\s"，如果匹配成功，则返回一个Match，否则返回一个None；第二个参数表示要匹配的字符串；第三个参数是标致位，用于控制正则表达式的匹配方式，如：是否区分大小写，多行匹配等等。re.search</summary><published>2010-12-06T12:04:00Z</published><updated>2010-12-06T12:04:00Z</updated><author><name>Seven_Yuan</name><uri>http://www.cnblogs.com/sevenyuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898075.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898075.html"/><content type="html">&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;今天学习了Python中有关正则表达式的知识。关于正则表达式的语法，不作过多解释，网上有许多学习的资料。这里主要介绍Python中常用的正则表达式处理函数。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-family: Times New Roman;"&gt;re.match&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;　　re.match 尝试从&lt;strong&gt;字符串的开始&lt;/strong&gt;匹配一个模式，如：下面的例子匹配第一个单词。 &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; re&lt;br /&gt;text &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;JGood is a handsome boy, he is cool, clever, and so on...&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;m &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; re.match(r&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;(\w+)\s&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, text)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; m:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; m.group(0), &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;, m.group(&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;not match&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;re.match的函数原型为：re.match(pattern, string, flags)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p style="padding-left: 30px;"&gt;&lt;span style="font-family: Times New Roman;"&gt;第一个参数是正则表达式，这里为"(\w+)\s"，如果匹配成功，则返回一个Match，否则返回一个None；&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p style="padding-left: 30px;"&gt;&lt;span style="font-family: Times New Roman;"&gt;第二个参数表示要匹配的字符串；&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p style="padding-left: 30px;"&gt;&lt;span style="font-family: Times New Roman;"&gt;第三个参数是标致位，用于控制正则表达式的匹配方式，如：是否区分大小写，多行匹配等等。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-family: Times New Roman;"&gt;re.search&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;　　re.search函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回，如果字符串没有匹配，则返回None。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; re&lt;br /&gt;text &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;JGood is a handsome boy, he is cool, clever, and so on...&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;m &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; re.search(r&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;\shan(ds)ome\s&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;, text)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; m:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; m.group(0), m.group(&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;not search&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;re.search的函数原型为： re.search(pattern, string, flags)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p style="padding-left: 30px;"&gt;&lt;span style="font-family: Times New Roman;"&gt;每个参数的含意与re.match一样。&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;&lt;strong&gt;re.match与re.search的区别：&lt;/strong&gt;re.match只匹配字符串的开始，如果字符串开始不符合正则表达式，则匹配失败，函数返回None；而re.search匹配整个字符串，直到找到一个匹配。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-family: Times New Roman;"&gt;re.sub&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;　　re.sub用于替换字符串中的匹配项。下面一个例子将字符串中的空格 ' ' 替换成 '-' :&amp;nbsp; &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; re&lt;br /&gt;text &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;JGood is a handsome boy, he is cool, clever, and so on...&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; re.sub(r&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;\s+&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;-&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;, text) &lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;re.sub的函数原型为：re.sub(pattern, repl, string, count)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p style="padding-left: 30px;"&gt;&lt;span style="font-family: Times New Roman;"&gt;其中第二个函数是替换后的字符串；本例中为'-'&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p style="padding-left: 30px;"&gt;&lt;span style="font-family: Times New Roman;"&gt;第四个参数指替换个数。默认为0，表示每个匹配项都替换。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;re.sub还允许使用函数对匹配项的替换进行复杂的处理。如：re.sub(r'\s', lambda m: '[' + m.group(0) + ']', text, 0)；将字符串中的空格' '替换为'[ ]'。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-family: Times New Roman;"&gt;re.split&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;　　可以使用re.split来分割字符串，如：re.split(r'\s+', text)；将字符串按空格分割成一个单词列表。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-family: Times New Roman;"&gt;re.findall&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;　　re.findall可以获取字符串中所有匹配的字符串。如：re.findall(r'\w*oo\w*', text)；获取字符串中，包含'oo'的所有单词。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-family: Times New Roman;"&gt;re.compile&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;　　可以把正则表达式编译成一个正则表达式对象。可以把那些经常使用的正则表达式编译成正则表达式对象，这样可以提高一定的效率。下面是一个正则表达式对象的一个例子：&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;span style="font-family: Times New Roman;"&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('902f4f5f-7a30-4104-b393-d554c9bc6007')"&gt;&#xD;
&lt;div id="cnblogs_code_open_902f4f5f-7a30-4104-b393-d554c9bc6007" &gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;import&lt;/span&gt;&lt;span style="color: #000000;"&gt; re&lt;br /&gt;text &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;JGood is a handsome boy, he is cool, clever, and so on...&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;regex &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; re.compile(r&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;\w*oo\w*&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; regex.findall(text)   &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;查找所有包含'oo'的单词&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt; regex.sub(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;lambda&lt;/span&gt;&lt;span style="color: #000000;"&gt; m: &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;[&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; m.group(0) &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;]&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;, text) &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;将字符串中含有'oo'的单词用[]括起来。&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Times New Roman;"&gt;转自：&lt;/span&gt;http://www.python8.org/a/fenleiwenzhang/yuyanjichu/2009/0901/150.html&lt;/p&gt;&lt;img src="http://www.cnblogs.com/sevenyuan/aggbug/1898075.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898075.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
