﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-无界-随笔分类-Boost</title><link>http://www.blogjava.net/LittleDS/category/31585.html</link><description>If the only tool you have is a hammer, you tend to see every problem as a nail.</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 02:28:54 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 02:28:54 GMT</pubDate><ttl>60</ttl><item><title>Boost Thread学习笔记五</title><link>http://www.blogjava.net/LittleDS/archive/2008/05/18/201280.html</link><dc:creator>杨磊</dc:creator><author>杨磊</author><pubDate>Sun, 18 May 2008 10:32:00 GMT</pubDate><guid>http://www.blogjava.net/LittleDS/archive/2008/05/18/201280.html</guid><wfw:comment>http://www.blogjava.net/LittleDS/comments/201280.html</wfw:comment><comments>http://www.blogjava.net/LittleDS/archive/2008/05/18/201280.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/LittleDS/comments/commentRss/201280.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/LittleDS/services/trackbacks/201280.html</trackback:ping><description><![CDATA[多线程编程中还有一个重要的概念：Thread&nbsp;Local&nbsp;Store（TLS，线程局部存储），在boost中，TLS也被称作TSS，Thread&nbsp;Specific&nbsp;Storage。<br />
boost<strong><font color="#663300">::</font></strong>thread库为我们提供了一个接口简单的TLS的面向对象的封装，以下是tss类的接口定义：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;tss<br />
{<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br />
&nbsp;&nbsp;&nbsp;&nbsp;tss(boost::function1</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*&gt;*</span><span style="color: #000000;">&nbsp;pcleanup);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;get()&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;set(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;cleanup(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;p);<br />
};</span></div>
<br />
分别用于获取、设置、清除线程局部存储变量，这些函数在内部封装了TlsAlloc、TlsGetValue、TlsSetValue等API操作，将它们封装成了OO的形式。<br />
但boost将该类信息封装在detail名字空间内，即不推荐我们使用，当需要使用tss时，我们应该使用另一个使用更加方便的类：thread_specific_ptr，这是一个智能指针类，该类的接口如下：<font color="#990000"><br />
<br />
</font>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;thread_specific_ptr&nbsp;:&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;boost::noncopyable&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Exposition&nbsp;only</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #0000ff;">public</span><span style="color: #000000;">:<br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;construct/copy/destruct</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;thread_specific_ptr();<br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;thread_specific_ptr(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">cleanup)(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">));<br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #000000;">~</span><span style="color: #000000;">thread_specific_ptr();<br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;modifier&nbsp;functions</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;release();<br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;reset(T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;observer&nbsp;functions</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;get()&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;operator</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">()&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;T</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;operator</span><span style="color: #000000;">*</span><span style="color: #000000;">()()&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">};</span></div>
<br />
即可支持get、reset、release等操作。<br />
thread_specific_ptr类的实现十分简单，仅仅为了将tss类&#8220;改装&#8221;成智
能指针的样子，该类在其构造函数中会自动创建一个tss对象，而在其析构函数中会调用默认参数的reset函数，从而引起内部被封装的tss对象被析构，
达到&#8220;自动&#8221;管理内存分配释放的目的。<br />
<br />
以下是一个运用thread_specific_ptr实现TSS的例子：<font color="#000099"><br />
</font>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">thread.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">mutex.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">tss.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">iostream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">boost::mutex&nbsp;io_mutex;<br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">boost::thread_specific_ptr</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;ptr;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;use&nbsp;this&nbsp;method&nbsp;to&nbsp;tell&nbsp;that&nbsp;this&nbsp;member&nbsp;will&nbsp;not&nbsp;shared&nbsp;by&nbsp;all&nbsp;threads</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">struct&nbsp;count<br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;count(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;id)&nbsp;:&nbsp;id(id)&nbsp;{&nbsp;}<br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;operator()()<br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(ptr.get()&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;if&nbsp;ptr&nbsp;is&nbsp;not&nbsp;initialized,&nbsp;initialize&nbsp;it</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptr.reset(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">(</span><span style="color: #000000;">0</span><span style="color: #000000;">));&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Attention,&nbsp;we&nbsp;pass&nbsp;a&nbsp;pointer&nbsp;to&nbsp;reset&nbsp;(actually&nbsp;set&nbsp;ptr)</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">10</span><span style="color: #000000;">;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">i)<br />
</span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">ptr)</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::mutex::scoped_lock&nbsp;lock(io_mutex);<br />
</span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;id&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">ptr&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;std::endl;<br />
</span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;id;<br />
</span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">};<br />
</span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">29</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;argc,&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;argv[])<br />
</span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd1(count(</span><span style="color: #000000;">1</span><span style="color: #000000;">));<br />
</span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd2(count(</span><span style="color: #000000;">2</span><span style="color: #000000;">));<br />
</span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;thrd1.join();<br />
</span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;thrd2.join();<br />
</span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;">}<br />
</span></div>
此外，thread库还提供了一个很有趣的函数，call_once，在tss<strong><font color="#663300">::</font></strong>init的实现中就用到了该函数。<br />
该函数的声明如下：<font color="#ff6633"><br />
void</font>&nbsp;call_once<strong><font color="#663300">(</font></strong><font color="#ff6633">void</font><strong><font color="#663300">&nbsp;(*</font></strong>func<strong><font color="#663300">)(),</font></strong>&nbsp;once_flag<strong><font color="#663300">&amp;</font></strong>&nbsp;flag<strong><font color="#663300">);</font></strong><br />
该函数的Windows实现通过创建一个Mutex使所有的线程在尝试执行该函数时处于等待状态，直到有一个线程执行完了func函数，该函数的第二个参数表示函数func是否已被执行，该参数往往被初始化成BOOST_ONCE_INIT（即<font color="#999900">0</font>），如果你将该参数初始化成<font color="#999900">1</font>，则函数func将不被调用，此时call_once相当于什么也没干，这在有时候可能是需要的，比如，根据程序处理的结果决定是否需要call_once某函数func。<br />
call_once在执行完函数func后，会将flag修改为<font color="#999900">1</font>，这样会导致以后执行call_once的线程（包括等待在Mutex处的线程和刚刚进入call_once的线程）都会跳过执行func的代码。<br />
<br />
需要注意的是，该函数不是一个模板函数，而是一个普通函数，它的第一个参数<font color="#999900">1</font>是一个函数指针，其类型为<font color="#ff6633">void</font><strong><font color="#663300">&nbsp;(*)()</font></strong>，而不是跟boost库的很多其它地方一样用的是function模板，不过这样也没有关系，有了boost<strong><font color="#663300">::</font></strong>bind这个超级武器，想怎么绑定参数就随你的便了，根据boost的文档，要求传入的函数不能抛出异常，但从实现代码中好像不是这样。<br />
<br />
以下是一个典型的运用call_once实现一次初始化的例子：<font color="#000099"><br />
<br />
</font>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">thread.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">once.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">iostream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;j&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">boost::once_flag&nbsp;flag&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;BOOST_ONCE_INIT;<br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;init()<br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">i;<br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">}<br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;thread()<br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::call_once(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">init,&nbsp;flag);<br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">j;<br />
</span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">}<br />
</span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">20</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;argc,&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;argv[])<br />
</span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd1(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">thread);<br />
</span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd2(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">thread);<br />
</span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;thrd1.join();<br />
</span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;thrd2.join();<br />
</span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;std::endl;<br />
</span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;j&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;std::endl;<br />
</span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">}</span></div>
结果显示，全局变量i仅被执行了一次<strong><font color="#663300">++</font></strong>操作，而变量j则在两个线程中均执行了<strong><font color="#663300">++</font></strong>操作。<br />
<font color="#000099"><br />
</font>
<img src ="http://www.blogjava.net/LittleDS/aggbug/201280.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/LittleDS/" target="_blank">杨磊</a> 2008-05-18 18:32 <a href="http://www.blogjava.net/LittleDS/archive/2008/05/18/201280.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Boost Thread学习笔记四</title><link>http://www.blogjava.net/LittleDS/archive/2008/05/18/201262.html</link><dc:creator>杨磊</dc:creator><author>杨磊</author><pubDate>Sun, 18 May 2008 08:48:00 GMT</pubDate><guid>http://www.blogjava.net/LittleDS/archive/2008/05/18/201262.html</guid><wfw:comment>http://www.blogjava.net/LittleDS/comments/201262.html</wfw:comment><comments>http://www.blogjava.net/LittleDS/archive/2008/05/18/201262.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/LittleDS/comments/commentRss/201262.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/LittleDS/services/trackbacks/201262.html</trackback:ping><description><![CDATA[barrier<br />
barrier类的接口定义如下：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;barrier&nbsp;:&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;boost::noncopyable&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Exposition&nbsp;only</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #0000ff;">public</span><span style="color: #000000;">:<br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;construct/copy/destruct</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;barrier(size_t&nbsp;n);<br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #000000;">~</span><span style="color: #000000;">barrier();<br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;waiting</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;bool&nbsp;wait();<br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">};</span></div>
<br />
barrier类为我们提供了这样一种控制线程同步的机制：<br />
前n<strong><font color="#663300">&nbsp;-</font></strong><font color="#999900">&nbsp;1</font>次调用wait函数将被阻塞，直到第n次调用wait函数，而此后第n<strong><font color="#663300">&nbsp;+</font></strong><font color="#999900">&nbsp;1</font>次到第2n<strong><font color="#663300">&nbsp;-</font></strong><font color="#999900">&nbsp;1</font>次调用wait也会被阻塞，直到第2n次调用，依次类推。<br />
barrier<strong><font color="#663300">::</font></strong>wait的实现十分简单：<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">barrier::barrier(unsigned&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;count)<br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;m_threshold(count),&nbsp;m_count(count),&nbsp;m_generation(</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(count&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">throw</span><span style="color: #000000;">&nbsp;std::invalid_argument(</span><span style="color: #000000;">"</span><span style="color: #000000;">count&nbsp;cannot&nbsp;be&nbsp;zero.</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">}<br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">bool&nbsp;barrier::wait()<br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::mutex::scoped_lock&nbsp;lock(m_mutex);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;m_mutex&nbsp;is&nbsp;the&nbsp;base&nbsp;of&nbsp;barrier&nbsp;and&nbsp;is&nbsp;initilized&nbsp;by&nbsp;it's&nbsp;default&nbsp;constructor.</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;gen&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;m_generation;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;m_generation&nbsp;will&nbsp;be&nbsp;0&nbsp;for&nbsp;call&nbsp;1~n-1,&nbsp;and&nbsp;1&nbsp;for&nbsp;n~2n&nbsp;-&nbsp;1,&nbsp;and&nbsp;so&nbsp;on<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span style="color: #008000;"><br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">--</span><span style="color: #000000;">m_count&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_generation</span><span style="color: #000000;">++</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;cause&nbsp;m_generation&nbsp;to&nbsp;be&nbsp;changed&nbsp;in&nbsp;call&nbsp;n/2n/<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span style="color: #008000;"><br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_count&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;m_threshold;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;reset&nbsp;count</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_cond.notify_all();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;wake&nbsp;up&nbsp;all&nbsp;thread&nbsp;waiting&nbsp;here</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(gen&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;m_generation)&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;if&nbsp;m_generation&nbsp;is&nbsp;not&nbsp;changed,&nbsp;lock&nbsp;current&nbsp;thread.</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_cond.wait(lock);<br />
</span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">}</span></div>
<br />
因此，说白了也不过是mutex的一个简单应用。<br />
以下是一个使用barrier的例子：<font color="#000099"><br />
<br />
</font>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">thread.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">barrier.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">boost::barrier&nbsp;barr(</span><span style="color: #000000;">3</span><span style="color: #000000;">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;call&nbsp;barr.wait&nbsp;3&nbsp;*&nbsp;n&nbsp;times&nbsp;will&nbsp;release&nbsp;all&nbsp;threads&nbsp;in&nbsp;waiting</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;thread()<br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">i;<br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;barr.wait();<br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">}<br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd1(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">thread);<br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd2(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">thread);<br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd3(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">thread);<br />
</span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;thrd1.join();<br />
</span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;thrd2.join();<br />
</span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;thrd3.join();<br />
</span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">}</span></div>
<br />
如果去掉其中thrd3相关的代码，将使得线程<font color="#999900">1</font>、<font color="#999900">2</font>一直处于wait状态，进而使得主线程无法退出。<br />
<br />
xtime<br />
xtime是boost<strong><font color="#663300">::</font></strong>thread中用来表示时间的一个辅助类，它是一个仅包含两个成员变量的结构体：<font color="#990000"><br />
<br />
</font>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">1</span>&nbsp;<span style="color: #000000;">struct&nbsp;xtime<br />
</span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">3</span>&nbsp;<span style="color: #008000;">//</span><span style="color: #008000;"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span style="color: #008000;"><br />
</span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;xtime_sec_t&nbsp;sec;<br />
</span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;xtime_nsec_t&nbsp;nsec;<br />
</span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;">};</span></div>
<br />
condition<strong><font color="#663300">::</font></strong>timed_wait、thread<strong><font color="#663300">::</font></strong>sleep等涉及超时的函数需要用到xtime。<br />
需要注意的是，xtime表示的不是一个时间间隔，而是一个时间点，因此使用起来很不方便。为了方便使用xtime，boost提供了一些辅助的xtime操作函数，如xtime_get、xtime_cmp等。<br />
以下是一个使用xtime来执行sleep的例子（跟简单的一句Sleep比起来，实在是太复杂了），其中用到了xtime初始化函数xtime_get：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">thread.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">xtime.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">iostream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::xtime&nbsp;xt;<br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::xtime_get(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">xt,&nbsp;boost::TIME_UTC);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;initialize&nbsp;xt&nbsp;with&nbsp;current&nbsp;time</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;xt.sec&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;change&nbsp;xt&nbsp;to&nbsp;next&nbsp;second</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread::sleep(xt);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;do&nbsp;sleep</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">1&nbsp;second&nbsp;sleep&nbsp;over.</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;std::endl;<br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">} <br />
</span></div>
<br />
<br />
<br />
<font color="#000099"><br />
</font>
<img src ="http://www.blogjava.net/LittleDS/aggbug/201262.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/LittleDS/" target="_blank">杨磊</a> 2008-05-18 16:48 <a href="http://www.blogjava.net/LittleDS/archive/2008/05/18/201262.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Boost Thread学习笔记三</title><link>http://www.blogjava.net/LittleDS/archive/2008/05/18/201261.html</link><dc:creator>杨磊</dc:creator><author>杨磊</author><pubDate>Sun, 18 May 2008 08:45:00 GMT</pubDate><guid>http://www.blogjava.net/LittleDS/archive/2008/05/18/201261.html</guid><wfw:comment>http://www.blogjava.net/LittleDS/comments/201261.html</wfw:comment><comments>http://www.blogjava.net/LittleDS/archive/2008/05/18/201261.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/LittleDS/comments/commentRss/201261.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/LittleDS/services/trackbacks/201261.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 下面先对condition_impl进行简要分析。condition_impl在其构造函数中会创建两个Semaphore（信号量）：m_gate、m_queue，及一个Mutex（互斥体，跟boost::mutex类似，但boost::mutex是基于CriticalSection&lt;临界区&gt;的）：m_mutex，其中：m_queue相当于当前所有等待线程的等待队列，构造函数...&nbsp;&nbsp;<a href='http://www.blogjava.net/LittleDS/archive/2008/05/18/201261.html'>阅读全文</a><img src ="http://www.blogjava.net/LittleDS/aggbug/201261.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/LittleDS/" target="_blank">杨磊</a> 2008-05-18 16:45 <a href="http://www.blogjava.net/LittleDS/archive/2008/05/18/201261.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Boost Thread学习笔记二</title><link>http://www.blogjava.net/LittleDS/archive/2008/05/18/201253.html</link><dc:creator>杨磊</dc:creator><author>杨磊</author><pubDate>Sun, 18 May 2008 08:20:00 GMT</pubDate><guid>http://www.blogjava.net/LittleDS/archive/2008/05/18/201253.html</guid><wfw:comment>http://www.blogjava.net/LittleDS/comments/201253.html</wfw:comment><comments>http://www.blogjava.net/LittleDS/archive/2008/05/18/201253.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/LittleDS/comments/commentRss/201253.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/LittleDS/services/trackbacks/201253.html</trackback:ping><description><![CDATA[除了thread，boost<strong><font color="#663300">::</font></strong>thread另一个重要组成部分是mutex，以及工作在mutex上的boost<strong><font color="#663300">::</font></strong>mutex<strong><font color="#663300">::</font></strong>scoped_lock、condition和barrier，这些都是为实现线程同步提供的。<br />
<br />
mutex<br />
boost提供的mutex有<font color="#999900">6</font>种：<br />
boost<strong><font color="#663300">::</font></strong>mutex<br />
boost<strong><font color="#663300">::</font></strong>try_mutex<br />
boost<strong><font color="#663300">::</font></strong>timed_mutex<br />
boost<strong><font color="#663300">::</font></strong>recursive_mutex<br />
boost<strong><font color="#663300">::</font></strong>recursive_try_mutex<br />
boost<strong><font color="#663300">::</font></strong>recursive_timed_mutex<br />
下面仅对boost<strong><font color="#663300">::</font></strong>mutex进行分析。<br />
mutex类是一个CriticalSection（临界区）封装类，它在构造函数中新建一个临界区并InitializeCriticalSection，然后用一个成员变量<font color="#ff6633"><br />
void</font><strong><font color="#663300">*</font></strong>&nbsp;m_mutex<strong><font color="#663300">;</font></strong><br />
来保存该临界区结构。<br />
除
此之外，mutex还提供了do_lock、do_unlock等方法，这些方法分别调用EnterCriticalSection、
LeaveCriticalSection来修改成员变量m_mutex（CRITICAL_SECTION结构指针）的状态，但这些方法都是<font color="#990000">private</font>的，以防止我们直接对mutex进行锁操作，所有的锁操作都必须通过mutex的友元类detail<strong><font color="#663300">::</font></strong>thread<strong><font color="#663300">::</font></strong>lock_ops<strong><font color="#663300">&lt;</font></strong>mutex<strong><font color="#663300">&gt;</font></strong>来完成，比较有意思的是，lock_ops的所有方法：lock、unlock、trylock等都是<font color="#990000">static</font>的，如lock_ops<strong><font color="#663300">&lt;</font></strong>Mutex<strong><font color="#663300">&gt;::</font></strong>lock的实现：<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 128, 128);">&nbsp;1</span>&nbsp;<span style="color: rgb(0, 0, 0);">template&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">typename&nbsp;Mutex</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;2</span>&nbsp;<span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;lock_ops&nbsp;:&nbsp;</span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">&nbsp;noncopyable<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;3</span>&nbsp;<span style="color: rgb(0, 0, 0);">{<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;4</span>&nbsp;<span style="color: rgb(0, 0, 0);"><img src="http://www.blogjava.net/Images/dot.gif" alt="" /><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;5</span>&nbsp;<span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;6</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;lock(Mutex</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;m)<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;7</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;8</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m.do_lock();<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;9</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: rgb(0, 128, 128);">10</span>&nbsp;<span style="color: rgb(0, 0, 0);"><img src="http://www.blogjava.net/Images/dot.gif" alt="" /><br />
</span><span style="color: rgb(0, 128, 128);">11</span>&nbsp;<span style="color: rgb(0, 0, 0);">}</span></div>
boost<strong><font color="#663300">::</font></strong>thread的设计者为什么会这么设计呢？我想大概是：<font color="#999900"><br />
1</font>、boost<strong><font color="#663300">::</font></strong>thread的设计者不希望被我们直接操作mutex，改变其状态，所以mutex的所有方法都是<font color="#990000">private</font>的（除了构造函数，析构函数）。<font color="#999900"><br />
2</font>、虽然我们可以通过lock_ops来修改mutex的状态，如：<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 128, 128);">&nbsp;1</span>&nbsp;<span style="color: rgb(0, 0, 0);">#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">boost</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">thread</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">thread.hpp</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;2</span>&nbsp;<span style="color: rgb(0, 0, 0);">#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">boost</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">thread</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">mutex.hpp</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;3</span>&nbsp;<span style="color: rgb(0, 0, 0);">#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">boost</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">thread</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">detail</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">lock.hpp</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;4</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;5</span>&nbsp;<span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;main()<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;6</span>&nbsp;<span style="color: rgb(0, 0, 0);">{<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;7</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;boost::mutex&nbsp;mt;<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;8</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">mt.do_lock();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;Error!&nbsp;Can&nbsp;not&nbsp;access&nbsp;private&nbsp;member!</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;9</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">10</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;boost::detail::thread::lock_ops</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">boost::mutex</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">::lock(mt);<br />
</span><span style="color: rgb(0, 128, 128);">11</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">12</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />
</span><span style="color: rgb(0, 128, 128);">13</span>&nbsp;<span style="color: rgb(0, 0, 0);">}</span></div>
但是，这是不推荐的，因为mutex、scoped_lock、condition、barrier是一套完整的类系，它们是相互协同工作的，像上面这么操作没有办法与后面的几个类协同工作。<br />
scoped_lock<br />
上面说过，不应该直接用lock_ops来操作mutex对象，那么，应该用什么呢？答案就是scoped_lock。与存在多种mutex一样，存在多种与mutex对应的scoped_lock：<br />
<br />
scoped_lock<br />
scoped_try_lock<br />
scoped_timed_lock<br />
<br />
这里我们只讨论scoped_lock。<br />
scoped_lock是定义在<font color="#990000">namespace</font>&nbsp;boost<strong><font color="#663300">::</font></strong>detail<strong><font color="#663300">::</font></strong>thread下的，为了方便我们使用（也为了方便设计者），mutex使用了下面的<font color="#990000">typedef</font>：<font color="#990000"><br />
typedef</font>&nbsp;detail<strong><font color="#663300">::</font></strong>thread<strong><font color="#663300">::</font></strong>scoped_lock<strong><font color="#663300">&lt;</font></strong>mutex<strong><font color="#663300">&gt;</font></strong>&nbsp;scoped_lock<strong><font color="#663300">;</font></strong><br />
这样我们就可以通过：<br />
boost<strong><font color="#663300">::</font></strong>mutex<strong><font color="#663300">::</font></strong>scoped_lock<br />
来使用scoped_lock类模板了。<br />
由于scoped_lock的作用仅在于对mutex加锁<strong><font color="#663300">/</font></strong>解锁（即使mutex&nbsp;EnterCriticalSection<strong><font color="#663300">/</font></strong>LeaveCriticalSection），因此，它的接口也很简单，除了构造函数外，仅有lock<strong><font color="#663300">/</font></strong>unlock<strong><font color="#663300">/</font></strong>locked（判断是否已加锁），及类型转换操作符<font color="#ff6633">void</font><strong><font color="#663300">*</font></strong>，一般我们不需要显式调用这些方法，因为scoped_lock的构造函数是这样定义的：<br />
<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 128, 128);">1</span>&nbsp;<span style="color: rgb(0, 0, 0);">explicit&nbsp;scoped_lock(Mutex</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;mx,&nbsp;bool&nbsp;initially_locked</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">)<br />
</span><span style="color: rgb(0, 128, 128);">2</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;m_mutex(mx),&nbsp;m_locked(</span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">)<br />
</span><span style="color: rgb(0, 128, 128);">3</span>&nbsp;<span style="color: rgb(0, 0, 0);">{<br />
</span><span style="color: rgb(0, 128, 128);">4</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(initially_locked)&nbsp;lock();<br />
</span><span style="color: rgb(0, 128, 128);">5</span>&nbsp;<span style="color: rgb(0, 0, 0);">}</span></div>
<br />
注：m_mutex是一个mutex的引用。<br />
因此，当我们不指定initially_locked参数构造一个scoped_lock对象
时，scoped_lock会自动对所绑定的mutex加锁，而析构函数会检查是否加锁，若已加锁，则解锁；当然，有些情况下，我们可能不需要构造时自动
加锁，这样就需要自己调用lock方法。后面的condition、barrier也会调用scoped_lock的lock、unlock方法来实现部
分方法。<br />
正因为scoped_lock具有可在构造时加锁，析构时解锁的特性，我们经常会使用局部变量来实现对mutex的独占访问。<br />
<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 128, 128);">&nbsp;1</span>&nbsp;<span style="color: rgb(0, 0, 0);">#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">boost</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">thread</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">thread.hpp</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;2</span>&nbsp;<span style="color: rgb(0, 0, 0);">#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">boost</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">thread</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">mutex.hpp</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;3</span>&nbsp;<span style="color: rgb(0, 0, 0);">#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">iostream</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;4</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;5</span>&nbsp;<span style="color: rgb(0, 0, 0);">boost::mutex&nbsp;io_mutex;<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;6</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;7</span>&nbsp;<span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;count()&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;worker&nbsp;function</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;8</span>&nbsp;<span style="color: rgb(0, 0, 0);">{<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;9</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">10</span><span style="color: rgb(0, 0, 0);">;&nbsp;</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">i)<br />
</span><span style="color: rgb(0, 128, 128);">10</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: rgb(0, 128, 128);">11</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::mutex::scoped_lock&nbsp;lock(io_mutex);<br />
</span><span style="color: rgb(0, 128, 128);">12</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;std::endl;<br />
</span><span style="color: rgb(0, 128, 128);">13</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: rgb(0, 128, 128);">14</span>&nbsp;<span style="color: rgb(0, 0, 0);">}<br />
</span><span style="color: rgb(0, 128, 128);">15</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">16</span>&nbsp;<span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;main(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;argc,&nbsp;</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;argv[])<br />
</span><span style="color: rgb(0, 128, 128);">17</span>&nbsp;<span style="color: rgb(0, 0, 0);">{<br />
</span><span style="color: rgb(0, 128, 128);">18</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd1(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">count);<br />
</span><span style="color: rgb(0, 128, 128);">19</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd2(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">count);<br />
</span><span style="color: rgb(0, 128, 128);">20</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;thrd1.join();<br />
</span><span style="color: rgb(0, 128, 128);">21</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;thrd2.join();<br />
</span><span style="color: rgb(0, 128, 128);">22</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">23</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />
</span><span style="color: rgb(0, 128, 128);">24</span>&nbsp;<span style="color: rgb(0, 0, 0);">}</span></div>
<br />
在每次输出信息时，为了防止整个输出过程被其它线程打乱，通过对io_mutex加锁（进入临界区），从而保证了输出的正确性。<br />
在使用
scoped_lock时，我们有时候需要使用全局锁（定义一个全局mutex，当需要独占访问全局资源时，以该全局mutex为参数构造一个
scoped_lock对象即可。全局mutex可以是全局变量，也可以是类的静态方法等），有时候则需要使用对象锁（将mutex定义成类的成员变
量），应该根据需要进行合理选择。<br />
Java的synchronized可用于对方法加锁，对代码段加锁，对对象加锁，对类加锁（仍然是对象级
的），这几种加锁方式都可以通过上面讲的对象锁来模拟；相反，在Java中实现全局锁好像有点麻烦，必须将请求封装到类中，以转换成上面的四种
synchronized形式之一。<br />
<br />
condition<br />
condition的接口如下：<font color="#990000"><br />
<br />
</font>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 128, 128);">&nbsp;1</span>&nbsp;<span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;condition&nbsp;:&nbsp;</span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">&nbsp;boost::noncopyable&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;Exposition&nbsp;only</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;2</span>&nbsp;<span style="color: rgb(0, 0, 0);">{<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;3</span>&nbsp;<span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;4</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;construct/copy/destruct</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;5</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;condition();<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;6</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);">condition();<br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;7</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;8</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;notification</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">&nbsp;9</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;notify_one();<br />
</span><span style="color: rgb(0, 128, 128);">10</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;notify_all();<br />
</span><span style="color: rgb(0, 128, 128);">11</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">12</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;waiting</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">13</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;template</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">typename&nbsp;ScopedLock</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;wait(ScopedLock</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">);<br />
</span><span style="color: rgb(0, 128, 128);">14</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;template</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">typename&nbsp;ScopedLock,&nbsp;typename&nbsp;Pred</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;wait(ScopedLock</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">,&nbsp;Pred);<br />
</span><span style="color: rgb(0, 128, 128);">15</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;template</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">typename&nbsp;ScopedLock</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">16</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;timed_wait(ScopedLock</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);">&nbsp;boost::xtime</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">);<br />
</span><span style="color: rgb(0, 128, 128);">17</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;template</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">typename&nbsp;ScopedLock,&nbsp;typename&nbsp;Pred</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 128, 128);">18</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;timed_wait(ScopedLock</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">,&nbsp;Pred);<br />
</span><span style="color: rgb(0, 128, 128);">19</span>&nbsp;<span style="color: rgb(0, 0, 0);">};</span></div>
<br />
其中wait用于等待某个condition的发生，而timed_wait则提供具有超时的wait功能，notify_one用于唤醒一个等待该condition发生的线程，notify_all则用于唤醒所有等待该condition发生的线程。<br />
<br />
由于condition的语义相对较为复杂，它的实现也是整个boost<strong><font color="#663300">::</font></strong>thread库中最复杂的（对Windows版本而言，对支持pthread的版本而言，由于pthread已经提供了pthread_cond_t，使得condition实现起来也十分简单），下面对wait和notify_one进行简要分析。<br />
condition内部包含了一个condition_impl对象，由该对象执行来处理实际的wait、notify_one<strong><font color="#663300">...</font></strong>等操作。<br />
<br />
<br />
<br />
<img src ="http://www.blogjava.net/LittleDS/aggbug/201253.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/LittleDS/" target="_blank">杨磊</a> 2008-05-18 16:20 <a href="http://www.blogjava.net/LittleDS/archive/2008/05/18/201253.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Boost Thread学习笔记</title><link>http://www.blogjava.net/LittleDS/archive/2008/05/18/201236.html</link><dc:creator>杨磊</dc:creator><author>杨磊</author><pubDate>Sun, 18 May 2008 06:49:00 GMT</pubDate><guid>http://www.blogjava.net/LittleDS/archive/2008/05/18/201236.html</guid><wfw:comment>http://www.blogjava.net/LittleDS/comments/201236.html</wfw:comment><comments>http://www.blogjava.net/LittleDS/archive/2008/05/18/201236.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/LittleDS/comments/commentRss/201236.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/LittleDS/services/trackbacks/201236.html</trackback:ping><description><![CDATA[thread自然是boost<strong><font color="#663300">::</font></strong>thread库的主
角，但thread类的实现总体上是比较简单的，前面已经说过，thread只是一个跨平台的线程封装库，其中按照所使用的编译选项的不同，分别决定使用
Windows线程API还是pthread，或者Macintosh&nbsp;Carbon平台的thread实现。以下只讨论Windows，即使用
BOOST_HAS_WINTHREADS的情况。<br />
thread类提供了两种构造函数：<br />
thread<strong><font color="#663300">::</font></strong>thread<strong><font color="#663300">()</font></strong><br />
thread<strong><font color="#663300">::</font></strong>thread<strong><font color="#663300">(</font></strong><font color="#990000">const</font>&nbsp;function0<strong><font color="#663300">&lt;</font></strong><font color="#ff6633">void</font><strong><font color="#663300">&gt;&amp;</font></strong>&nbsp;threadfunc<strong><font color="#663300">)</font></strong><br />
第
一种构造函数用于调用GetCurrentThread构造一个当前线程的thread对象，第二种则通过传入一个函数或者一个functor来创建一个
新的线程。第二种情况下，thread类在其构造函数中间接调用CreateThread来创建线程，并将线程句柄保存到成员变量m_thread中，并
执行传入的函数，或执行functor的<font color="#990000">operator</font><strong><font color="#663300">&nbsp;()</font></strong>方法来启动工作线程。<br />
<br />
我们可以用以下三种方式启动一个新线程：<font color="#999900"><br />
1</font>、传递一个工作函数来构造一个工作线程<font color="#000099"><br />
<br />
</font>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">thread.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">mutex.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">iostream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">boost::mutex&nbsp;io_mutex;<br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;count()&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;worker&nbsp;function</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">10</span><span style="color: #000000;">;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">i)<br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::mutex::scoped_lock&nbsp;lock(io_mutex);<br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;std::endl;<br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">}<br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;argc,&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;argv[])<br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd1(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">count);<br />
</span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd2(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">count);<br />
</span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;thrd1.join();<br />
</span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;thrd2.join();<br />
</span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">}<br />
</span><span style="color: #008080;">25</span>&nbsp;</div>
<br />
<font color="#999900">2</font>、传递一个functor对象来构造一个工作线程<font color="#000099"><br />
<br />
</font>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">thread.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">mutex.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">iostream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">boost::mutex&nbsp;io_mutex;<br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">struct&nbsp;count<br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;count(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;id)&nbsp;:&nbsp;id(id)&nbsp;{&nbsp;}<br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;operator()()<br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">10</span><span style="color: #000000;">;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">i)<br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::mutex::scoped_lock&nbsp;lock(io_mutex);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;lock&nbsp;io,&nbsp;will&nbsp;be&nbsp;explained&nbsp;soon.</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;id&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;std::endl;<br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;id;<br />
</span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">};<br />
</span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">23</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;argc,&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;argv[])<br />
</span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd1(count(</span><span style="color: #000000;">1</span><span style="color: #000000;">));<br />
</span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd2(count(</span><span style="color: #000000;">2</span><span style="color: #000000;">));<br />
</span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;thrd1.join();<br />
</span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;thrd2.join();<br />
</span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">}<br />
</span><span style="color: #008080;">31</span>&nbsp;</div>
<br />
<font color="#999900">3</font>、无需将类设计成一个functor，借助bind来构造functor对象以创建工作线程<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">thread.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">thread</span><span style="color: #000000;">/</span><span style="color: #000000;">mutex.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">boost</span><span style="color: #000000;">/</span><span style="color: #000000;">bind.hpp</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">iostream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">boost::mutex&nbsp;io_mutex;<br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">struct&nbsp;count<br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;num;<br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;id;<br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;count()&nbsp;:&nbsp;id(num</span><span style="color: #000000;">++</span><span style="color: #000000;">)&nbsp;{}<br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;do_count(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n)<br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;n;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">i)<br />
</span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::mutex::scoped_lock&nbsp;lock(io_mutex);<br />
</span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;id&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;std::endl;<br />
</span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;id;<br />
</span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">};<br />
</span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">26</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;count::num&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">28</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;argc,&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;argv[])<br />
</span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;count&nbsp;c1;<br />
</span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;boost::thread&nbsp;thrd1(boost::bind(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">count::do_count,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">c1,&nbsp;</span><span style="color: #000000;">10</span><span style="color: #000000;">));<br />
</span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;thrd1.join();<br />
</span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">}<br />
</span></div>
<br />
其中bind是一个函数模板，它可以根据后面的实例化参数构造出一个functor来，上面的boost<strong><font color="#663300">::</font></strong>bind<strong><font color="#663300">(&amp;</font></strong>count<strong><font color="#663300">::</font></strong>do_count<strong><font color="#663300">,&nbsp;&amp;</font></strong>c1<strong><font color="#663300">,</font></strong><font color="#999900">&nbsp;10</font><strong><font color="#663300">)</font></strong>其实等价于返回了一个functor：<font color="#990000"><br />
struct</font>&nbsp;countFunctor<strong><font color="#663300"><br />
{</font></strong><font color="#ff6633"><br />
&nbsp;&nbsp;&nbsp;&nbsp;int</font><font color="#990000">&nbsp;operator</font><strong><font color="#663300">()&nbsp;()<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&amp;</font></strong>c1<strong><font color="#663300">)-&gt;</font></strong>do_count<strong><font color="#663300">(</font></strong><font color="#999900">10</font><strong><font color="#663300">);</font></strong><em><font color="#999999">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;just&nbsp;a&nbsp;hint,&nbsp;not&nbsp;actual&nbsp;code<br />
</font></em><strong><font color="#663300">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
};</font></strong><br />
因此，以后就跟<font color="#999900">2</font>中是一样的了。<br />
<br />
<br />
<img src ="http://www.blogjava.net/LittleDS/aggbug/201236.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/LittleDS/" target="_blank">杨磊</a> 2008-05-18 14:49 <a href="http://www.blogjava.net/LittleDS/archive/2008/05/18/201236.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>