﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Error-文章分类-about boost</title><link>http://www.cppblog.com/Error/category/18452.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 05 Feb 2013 10:55:14 GMT</lastBuildDate><pubDate>Tue, 05 Feb 2013 10:55:14 GMT</pubDate><ttl>60</ttl><item><title>转  用boost共享锁实现读写锁造成死锁问题 </title><link>http://www.cppblog.com/Error/articles/197659.html</link><dc:creator>Enic</dc:creator><author>Enic</author><pubDate>Thu, 31 Jan 2013 10:46:00 GMT</pubDate><guid>http://www.cppblog.com/Error/articles/197659.html</guid><wfw:comment>http://www.cppblog.com/Error/comments/197659.html</wfw:comment><comments>http://www.cppblog.com/Error/articles/197659.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Error/comments/commentRss/197659.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Error/services/trackbacks/197659.html</trackback:ping><description><![CDATA[<div class="article_title" sizset="25" sizcache="0">&nbsp;</div>
<div id="article_content" class="article_content" sizset="0" sizcache="1">
<blockquote style="margin-right: 0px" dir="ltr" sizset="0" sizcache="1">
<p>网上很容易找到一个用boost::shared_mutex来作为读写锁的例子：</p>
<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools"><strong>[cpp]</strong> <a class="ViewSource" title="view plain" href="http://blog.csdn.net/jxlczjp77/article/details/8277759#"><u><font color="#0000ff">view plain</font></u></a><a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/jxlczjp77/article/details/8277759#"><u><font color="#0000ff">copy</font></u></a><a class="PrintSource" title="print" href="http://blog.csdn.net/jxlczjp77/article/details/8277759#"><u><font color="#0000ff">print</font></u></a><a class="About" title="?" href="http://blog.csdn.net/jxlczjp77/article/details/8277759#"><u><font color="#0000ff">?</font></u></a></div></div>
<ol class="dp-cpp"><li class="alt"><span class="keyword">typedef</span><span>&nbsp;boost::shared_mutex&nbsp;rwmutex;&nbsp;&nbsp;</span></li><li><span></span><span class="keyword">typedef</span><span>&nbsp;boost::shared_lock&lt;rwmutex&gt;&nbsp;readLock;&nbsp;&nbsp;</span></span></li><li class="alt"><span></span><span class="keyword">typedef</span><span>&nbsp;boost::unique_lock&lt;rwmutex&gt;&nbsp;writeLock;&nbsp;&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none" class="cpp" name="code">typedef boost::shared_mutex rwmutex;
typedef boost::shared_lock&lt;rwmutex&gt; readLock;
typedef boost::unique_lock&lt;rwmutex&gt; writeLock;&nbsp;</pre>
<p>&nbsp;</p>
<p>一直没有怀疑过这个做法，直到最近项目中出现一个死锁问题，查了很久才发现是上面这种写法造成的。</p>
<p>写测试代码还原死锁的情景如下：</p>
<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools"><strong>[cpp]</strong> <a class="ViewSource" title="view plain" href="http://blog.csdn.net/jxlczjp77/article/details/8277759#"><u><font color="#0000ff">view plain</font></u></a><a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/jxlczjp77/article/details/8277759#"><u><font color="#0000ff">copy</font></u></a><a class="PrintSource" title="print" href="http://blog.csdn.net/jxlczjp77/article/details/8277759#"><u><font color="#0000ff">print</font></u></a><a class="About" title="?" href="http://blog.csdn.net/jxlczjp77/article/details/8277759#"><u><font color="#0000ff">?</font></u></a></div></div>
<ol class="dp-cpp"><li class="alt"><span class="preprocessor">#include&nbsp;&lt;boost/thread/shared_mutex.hpp&gt; </span><span>&nbsp;&nbsp;</span></li><li><span></span><span class="preprocessor">#include&nbsp;&lt;boost/thread/shared_lock_guard.hpp&gt; </span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span></span><span class="preprocessor">#include&nbsp;&lt;boost/thread.hpp&gt; </span><span>&nbsp;&nbsp;</span></span></li><li><span></span><span class="preprocessor">#include&nbsp;&lt;iostream&gt; </span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span></span><span class="preprocessor">#include&nbsp;&lt;Windows.h&gt; </span><span>&nbsp;&nbsp;</span></span></li><li><span></span><span class="keyword">using</span><span>&nbsp;</span><span class="keyword">namespace</span><span>&nbsp;std;&nbsp;&nbsp;</span></span></li><li class="alt"><span></span><span class="keyword">typedef</span><span>&nbsp;boost::shared_mutex&nbsp;rwmutex;&nbsp;&nbsp;</span></span></li><li><span></span><span class="keyword">typedef</span><span>&nbsp;boost::shared_lock&lt;rwmutex&gt;&nbsp;readLock;&nbsp;&nbsp;</span></span></li><li class="alt"><span></span><span class="keyword">typedef</span><span>&nbsp;boost::unique_lock&lt;rwmutex&gt;&nbsp;writeLock;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>rwmutex&nbsp;m_mutex;&nbsp;&nbsp;</span></li><li><span></span><span class="keyword">void</span><span>&nbsp;func1()&nbsp;&nbsp;</span></span></li><li class="alt"><span>{&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;writeLock&nbsp;lock1(m_mutex);&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;</span><span class="string">"fffffffffffffff"</span><span>&nbsp;&lt;&lt;&nbsp;endl;&nbsp;&nbsp;</span></span></li><li><span>}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li><span></span><span class="datatypes">int</span><span>&nbsp;main()&nbsp;&nbsp;</span></span></li><li class="alt"><span>{&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::</span><span class="keyword">thread</span><span>&nbsp;tt(func1);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock&nbsp;lock(m_mutex);&nbsp;</span><span class="comment">//&nbsp;加读锁 </span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sleep(3000);&nbsp;&nbsp;</span><span class="comment">//&nbsp;故意睡眠3秒将线程切换出去 </span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock&nbsp;lock(m_mutex);&nbsp;</span><span class="comment">//&nbsp;醒来后再次加读锁 </span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;</span><span class="string">"rrrrrrrrrrrrrrrrrr"</span><span>&nbsp;&lt;&lt;&nbsp;endl;&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li></ol></div><pre style="display: none" class="cpp" name="code">#include &lt;boost/thread/shared_mutex.hpp&gt;
#include &lt;boost/thread/shared_lock_guard.hpp&gt;
#include &lt;boost/thread.hpp&gt;
#include &lt;iostream&gt;
#include &lt;Windows.h&gt;
using namespace std;
typedef boost::shared_mutex rwmutex;
typedef boost::shared_lock&lt;rwmutex&gt; readLock;
typedef boost::unique_lock&lt;rwmutex&gt; writeLock;

rwmutex m_mutex;
void func1()
{
	writeLock lock1(m_mutex);
	cout &lt;&lt; "fffffffffffffff" &lt;&lt; endl;
}

int main()
{
	{
		boost::thread tt(func1);
		readLock lock(m_mutex); // 加读锁
		{
			Sleep(3000);  // 故意睡眠3秒将线程切换出去
			readLock lock(m_mutex); // 醒来后再次加读锁
			cout &lt;&lt; "rrrrrrrrrrrrrrrrrr" &lt;&lt; endl;
		}
	}
}</pre>
<p>情形描述如下：</p>
<p>1：主线程先给m_mutex加读锁。</p>
<p>2：主线程故意睡眠3秒将执行权限切换出去。</p>
<p>3：func1线程获得执行机会，尝试加写锁被挂起。因为主线程已经有一个读锁占用，写锁必须等待这个读锁释放才能进入。</p>
<p>4：主线程睡眠3秒醒来，后续代码想获取一个读锁。由于这个时候已经有一个写锁在等待进入，那么这个读锁排队在写锁后面，同样被挂起。</p>
<p>5：主线程和func1线程都被挂起了，发生死锁。</p>
<p>上面的测试代码，如果中间没有sleep(3000)，出现死锁的概率很低，但总归是存在死锁的可能。</p>
<p>&nbsp;</p>
<p>总结：</p>
<p>以前一直认为readLock锁和递归锁一样，在同一个线程多次进入没有关系才会造成上面的死锁出现。所以，boost::shared_lock使用要小心，千万不要同一个线程多次进入。</p></blockquote></div><img src ="http://www.cppblog.com/Error/aggbug/197659.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Error/" target="_blank">Enic</a> 2013-01-31 18:46 <a href="http://www.cppblog.com/Error/articles/197659.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转) 条款17：以独立语句将newed对象置入智能指针</title><link>http://www.cppblog.com/Error/articles/195114.html</link><dc:creator>Enic</dc:creator><author>Enic</author><pubDate>Tue, 13 Nov 2012 07:41:00 GMT</pubDate><guid>http://www.cppblog.com/Error/articles/195114.html</guid><wfw:comment>http://www.cppblog.com/Error/comments/195114.html</wfw:comment><comments>http://www.cppblog.com/Error/articles/195114.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Error/comments/commentRss/195114.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Error/services/trackbacks/195114.html</trackback:ping><description><![CDATA[<p><span>Effective C</span><span style="font-family: 宋体">＋＋</span></p>
<p><span style="font-family: 宋体">条款</span><span>17</span><span style="font-family: 宋体">：以独立语句将</span><span>newed</span><span style="font-family: 宋体">对象置入智能指针</span></p>
<p><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Stroe newed objects in smart pointers in standalone statements<span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">请记住：</span></p>
<p><span style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">1．<span style="font: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="font-family: 宋体">以独立语句将</span><span>newed</span><span style="font-family: 宋体">对象存储于（置入）智能指针内。如果不这样做，一旦异常被抛出，有可能导致难以察觉的资源泄漏。</span></p>
<p><span style="font-family: 宋体">&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;</span></p>
<p><span>int priority();</span></p>Widget&gt; pw,int priority);</span> 
<p>&nbsp;</p>
<p><span style="font-family: 宋体">&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;</span></p>Widget&gt;(new Widget),priority());</span> 
<p>&nbsp;</p>
<p><span style="font-family: 宋体">在调用</span><span>processWidget</span><span style="font-family: 宋体">之前，编译器必须创建代码，做以下三件事：</span></p>
<p><span style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">1．<span style="font: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="font-family: 宋体">调用</span><span>priority</span></p>
<p><span style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">2．<span style="font: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="font-family: 宋体">执行&#8220;</span><span>new Widget</span><span style="font-family: 宋体">&#8221;</span></p>
<p><span style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">3．<span style="font: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="font-family: 宋体">调用</span><span>trl::shared_ptr</span><span style="font-family: 宋体">构造函数。</span></p>
<p><span style="font-family: 宋体">顺序不定，但</span><span>2</span><span style="font-family: 宋体">一定执行于</span><span>3</span><span style="font-family: 宋体">的前面。</span></p>
<p><span style="font-family: 宋体">如果执行顺序是以下：</span></p>
<p><span>1</span><span style="font-family: 宋体">．执行&#8220;</span><span>new Widget</span><span style="font-family: 宋体">&#8221;</span></p>
<p><span>2</span><span style="font-family: 宋体">．调用</span><span>priority</span></p>
<p><span>3</span><span style="font-family: 宋体">．调用</span><span>trl::shared_ptr</span><span style="font-family: 宋体">构造函数。</span></p>
<p><span style="font-family: 宋体">此种情况下，万一对</span><span>priority</span><span style="font-family: 宋体">的调用导致异常，&#8220;</span><span>new Widget</span><span style="font-family: 宋体">&#8221;返回的指针将会遗失，因为它尚未被置入</span><span>trl::shared_ptr</span><span style="font-family: 宋体">内。</span></p>
<p><span style="font-family: 宋体">&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;&#8213;</span></p>
<p><span style="font-family: 宋体">解决办法：以独立的语句将</span><span>newed</span><span style="font-family: 宋体">对象置入智能指针。</span></p>Widget&gt; pw(new Widget);</span> 
<p>&nbsp;</p>
<p><span>processWidget(pw,priority());</span></p><img src ="http://www.cppblog.com/Error/aggbug/195114.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Error/" target="_blank">Enic</a> 2012-11-13 15:41 <a href="http://www.cppblog.com/Error/articles/195114.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>危险的boost::bind</title><link>http://www.cppblog.com/Error/articles/163514.html</link><dc:creator>Enic</dc:creator><author>Enic</author><pubDate>Tue, 03 Jan 2012 15:00:00 GMT</pubDate><guid>http://www.cppblog.com/Error/articles/163514.html</guid><wfw:comment>http://www.cppblog.com/Error/comments/163514.html</wfw:comment><comments>http://www.cppblog.com/Error/articles/163514.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Error/comments/commentRss/163514.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Error/services/trackbacks/163514.html</trackback:ping><description><![CDATA[boost::bind 在进行参数绑定的时候，如果绑定的是一个对象，而且对象的声明周期很重要，证明你要开始悲剧了。<br />直接上图吧：<br /><img src="http://www.cppblog.com/images/cppblog_com/error/boost_bind.jpg" width="990" height="530" alt="" /><br /><br />我不过是轻轻的bind了一下，结果出来这么多析构，难道是啥魔法不成，，，<br />回头一想三架马车还有俩没上来，，，<br /><img src="http://www.cppblog.com/images/cppblog_com/error/boost_bind1.jpg" width="1006" height="534" alt="" /><br /><br />各种构造，各种析构，，，<br /><br /><br />bind应该产生了一个类似functor的东东，保持了一份参数的拷贝，，，<br />复习了下数数，构造和析构的个数是一样的，，，所以bind如果传递shared_ptr是安全的，，，<br /><br />不过shared_ptr中有interlock操作，效率，，，<img src ="http://www.cppblog.com/Error/aggbug/163514.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Error/" target="_blank">Enic</a> 2012-01-03 23:00 <a href="http://www.cppblog.com/Error/articles/163514.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>