2013-01-21 76 views
3

運行helgrind中官方boos asio示例代碼的示例時,會出現警告。這從文件boost/asio/detail/posix_event.hpp代碼似乎是警告的原因:使用helgrind提升asio http async_client示例警告:假陽性?

// Signal the event and unlock the mutex. 
template <typename Lock> 
void signal_and_unlock(Lock& lock) 
{ 
    BOOST_ASSERT(lock.locked()); 
    signalled_ = true; 
    lock.unlock(); 
    ::pthread_cond_signal(&cond_); // Ignore EINVAL. 
} 

這裏是Valgrind的全力輸出/ helgrind:

[email protected]:~/samples/async-client/build$ valgrind --tool=helgrind ./async-client stackoverflow.com error.html 
==2894== Helgrind, a thread error detector 
==2894== Copyright (C) 2007-2011, and GNU GPL'd, by OpenWorks LLP et al. 
==2894== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info 
==2894== Command: ./async-client stackoverflow.com error.html 
==2894== 
==2894== ---Thread-Announcement------------------------------------------ 
==2894== 
==2894== Thread #1 is the program's root thread 
==2894== 
==2894== ---------------------------------------------------------------- 
==2894== 
==2894== Thread #1: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread 
==2894== at 0x4C2C978: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==2894== by 0x4C2E5EA: [email protected]* (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) 
==2894== by 0x43FCB2: void boost::asio::detail::posix_event::signal_and_unlock<boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex> >(boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>&) (in /home/jcm/samples/async-client/build/async-client) 
==2894== by 0x43B659: boost::asio::detail::task_io_service::wake_one_idle_thread_and_unlock(boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>&) (in /home/jcm/samples/async-client/build/async-client) 
==2894== by 0x43B68A: boost::asio::detail::task_io_service::wake_one_thread_and_unlock(boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>&) (in /home/jcm/samples/async-client/build/async-client) 
==2894== by 0x43B0B8: boost::asio::detail::task_io_service::post_immediate_completion(boost::asio::detail::task_io_service_operation*) (in /home/jcm/samples/async-client/build/async-client) 
==2894== by 0x43DBFD: boost::asio::detail::resolver_service_base::start_resolve_op(boost::asio::detail::task_io_service_operation*) (in /home/jcm/samples/async-client/build/async-client) 
==2894== by 0x442F86: void boost::asio::detail::resolver_service<boost::asio::ip::tcp>::async_resolve<boost::_bi::bind_t<void, boost::_mfi::mf2<void, client, boost::system::error_code const&, boost::asio::ip::basic_resolver_iterator<boost::asio::ip::tcp> >, boost::_bi::list3<boost::_bi::value<client*>, boost::arg<1> (*)(), boost::arg<2> (*)()> > >(std::shared_ptr<void>&, boost::asio::ip::basic_resolver_query<boost::asio::ip::tcp> const&, boost::_bi::bind_t<void, boost::_mfi::mf2<void, client, boost::system::error_code const&, boost::asio::ip::basic_resolver_iterator<boost::asio::ip::tcp> >, boost::_bi::list3<boost::_bi::value<client*>, boost::arg<1> (*)(), boost::arg<2> (*)()> >) (in /home/jcm/samples/async-client/build/async-client) 
==2894== by 0x44187E: void boost::asio::ip::resolver_service<boost::asio::ip::tcp>::async_resolve<boost::_bi::bind_t<void, boost::_mfi::mf2<void, client, boost::system::error_code const&, boost::asio::ip::basic_resolver_iterator<boost::asio::ip::tcp> >, boost::_bi::list3<boost::_bi::value<client*>, boost::arg<1> (*)(), boost::arg<2> (*)()> > >(std::shared_ptr<void>&, boost::asio::ip::basic_resolver_query<boost::asio::ip::tcp> const&, boost::_bi::bind_t<void, boost::_mfi::mf2<void, client, boost::system::error_code const&, boost::asio::ip::basic_resolver_iterator<boost::asio::ip::tcp> >, boost::_bi::list3<boost::_bi::value<client*>, boost::arg<1> (*)(), boost::arg<2> (*)()> >&&) (in /home/jcm/samples/async-client/build/async-client) 
==2894== by 0x44097E: void boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::ip::resolver_service<boost::asio::ip::tcp> >::async_resolve<boost::_bi::bind_t<void, boost::_mfi::mf2<void, client, boost::system::error_code const&, boost::asio::ip::basic_resolver_iterator<boost::asio::ip::tcp> >, boost::_bi::list3<boost::_bi::value<client*>, boost::arg<1> (*)(), boost::arg<2> (*)()> > >(boost::asio::ip::basic_resolver_query<boost::asio::ip::tcp> const&, boost::_bi::bind_t<void, boost::_mfi::mf2<void, client, boost::system::error_code const&, boost::asio::ip::basic_resolver_iterator<boost::asio::ip::tcp> >, boost::_bi::list3<boost::_bi::value<client*>, boost::arg<1> (*)(), boost::arg<2> (*)()> >&&) (in /home/jcm/samples/async-client/build/async-client) 
==2894== by 0x43E05F: client::client(boost::asio::io_service&, std::string const&, std::string const&) (in /home/jcm/samples/async-client/build/async-client) 
==2894== by 0x437018: main (in /home/jcm/samples/async-client/build/async-client) 
==2894== 
Response returned with status code 400 
==2894== 
==2894== For counts of detected and suppressed errors, rerun with: -v 
==2894== Use --history-level=approx or =none to gain increased speed, at 
==2894== the cost of reduced accuracy of conflicting-access information 
==2894== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 89 from 29) 

我似乎是錯誤的,我認爲互斥量前解鎖條件變量被髮信號。如果這是誤報,請讓我知道爲什麼上述代碼是正確的。

回答

4

。假定lock是因爲這是在匹配調用中使用pthread_cond_(timed)wait非常相同的pthread_mutex_t對象的包裝對象,並行線程可以讓你發出的信號,並以任何順序解鎖的大多數實現,因爲pthread_cond_(timed)wait被定義爲解鎖條件變量並獲取互斥鎖作爲原子操作 - 也就是說,它將不會成功返回,直到均爲 CV已被髮信號並且調用線程已獲取互斥鎖。

網上傳言表明,沒有人失敗此操作不管它是什麼樣的順序中,但一些線程調度程序都獲得最大效率當信號後解鎖發生被寫入 - 和別人已經爲最大效率時寫解鎖發生在信號之前,這意味着無論您如何編寫它,您都無法贏得所有時間。就個人而言,如果我維護有問題的代碼,我會改變命令,理由是它使helgrind高興。你不想通過垃圾投訴來尋找真正的競爭條件。

而且,我添加「pthread_cond_signal應該同時使用CV和互斥體,就像pthread_cond_wait」,以便在我獲得時間機器時修復POSIX API錯誤列表。

+0

感謝您的回答。我學到了東西。與此同時,我還發現這[博客文章](http://www.domaigne.com/blog/computing/condvars-signal-with-mutex-locked-or-not/) – jcm