簡體   English   中英

Helgrind 在簡單的 boost::asio::thread_pool 程序中報告同步錯誤

[英]Helgrind reports synchronization errors in simple boost::asio::thread_pool program

我正在試驗 boost::asio::thread_pool,helgrind 在一個簡單的程序中報告錯誤,該程序具有空任務 function。問題出在哪里,我該如何解決?


#include <boost/thread/mutex.hpp>
#include <boost/thread.hpp>
#include <boost/asio/thread_pool.hpp>
#include <boost/asio/post.hpp>


int main() {
    ushort thread_num = 4;
    boost::asio::thread_pool pool(thread_num);

    auto task = []() {};

    for (ushort i = 0; i < thread_num; ++i)
        boost::asio::post(pool, task);

    pool.join();

    return 0;
}

這是 helgrind output:

==266706== Thread #1 is the program's root thread
==266706== 
==266706== ----------------------------------------------------------------
==266706== 
==266706== Thread #1: pthread_cond_{signal,broadcast}: dubious: associated lock is not held by any thread
==266706==    at 0x48405D6: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so)
==266706==    by 0x11508D: bool boost::asio::detail::posix_event::maybe_unlock_and_signal_one<boost::asio::detail::conditionally_enabled_mutex::scoped_lock>(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&) (in /home/arno/Programming/test/a.out)
==266706==    by 0x111AAD: boost::asio::detail::conditionally_enabled_event::maybe_unlock_and_signal_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&) (in /home/arno/Programming/test/a.out)
==266706==    by 0x11361E: boost::asio::detail::scheduler::wake_one_thread_and_unlock(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&) (in /home/arno/Programming/test/a.out)
==266706==    by 0x1132C4: boost::asio::detail::scheduler::post_immediate_completion(boost::asio::detail::scheduler_operation*, bool) (in /home/arno/Programming/test/a.out)
==266706==    by 0x10DD99: void boost::asio::thread_pool::executor_type::post<boost::asio::detail::work_dispatcher<main::{lambda()#1}>, std::allocator<void> >(boost::asio::detail::work_dispatcher<main::{lambda()#1}>&&, std::allocator<void> const&) const (in /home/arno/Programming/test/a.out)
==266706==    by 0x10DBFB: void boost::asio::detail::initiate_post::operator()<main::{lambda()#1}&, boost::asio::thread_pool::executor_type const&>(main::{lambda()#1}&, boost::asio::thread_pool::executor_type const&) const (in /home/arno/Programming/test/a.out)
==266706==    by 0x10DB82: void boost::asio::async_result<main::{lambda()#1}, void ()>::initiate<boost::asio::detail::initiate_post, {lambda()#1}&, boost::asio::thread_pool::executor_type const&>(boost::asio::detail::initiate_post&&, {lambda()#1}&, boost::asio::thread_pool::executor_type const&) (in /home/arno/Programming/test/a.out)
==266706==    by 0x10DB54: std::enable_if<void ()::async_result_has_initiate_memfn<main::{lambda()#1}&, void ()>::value, boost::asio::async_result<std::decay<void ()::async_result_has_initiate_memfn>::type, main::{lambda()#1}&>::return_type>::type boost::asio::async_initiate<main::{lambda()#1}&, void (), boost::asio::detail::initiate_post, boost::asio::thread_pool::executor_type const&>(boost::asio::detail::initiate_post&&, void (&)()::async_result_has_initiate_memfn, boost::asio::thread_pool::executor_type const&) (in /home/arno/Programming/test/a.out)
==266706==    by 0x10DB12: boost::asio::async_result<std::decay<main::{lambda()#1}&>::type, void ()>::return_type boost::asio::post<boost::asio::thread_pool::executor_type, main::{lambda()#1}&>(boost::asio::thread_pool::executor_type const&, std::decay&&, std::enable_if<boost::asio::is_executor<boost::asio::async_result<std::decay<main::{lambda()#1}&>::type, void ()>::return_type>::value, void>::type*) (in /home/arno/Programming/test/a.out)
==266706==    by 0x10DABD: boost::asio::async_result<std::decay<main::{lambda()#1}&>::type, void ()>::return_type boost::asio::post<boost::asio::thread_pool, main::{lambda()#1}&>(boost::asio::thread_pool&, std::decay&&, std::enable_if<std::is_convertible<boost::asio::thread_pool, boost::asio::execution_context&>::value, void>::type*) (in /home/arno/Programming/test/a.out)
==266706==    by 0x10DA11: main (in /home/arno/Programming/test/a.out)

https://linux.die.net/man/3/pthread_cond_signal

線程可以調用 pthread_cond_broadcast() 或 pthread_cond_signal() 函數,無論它當前是否擁有調用 pthread_cond_wait() 或 pthread_cond_timedwait() 的線程在等待期間與條件變量相關聯的互斥體; 但是,如果需要可預測的調度行為,則該互斥量應由調用 pthread_cond_broadcast() 或 pthread_cond_signal() 的線程鎖定。

這只是一個診斷警告,指示圍繞條件變量進行低效調度的常見原因。 如果您(作為生產者)在發出信號時沒有保持互斥鎖鎖定,您會得到虛假的喚醒。 例如,您對 CV 變量的更新可能在您解鎖互斥量后立即得到處理,因此您的信號會導致另一個不必要的喚醒,而 state 沒有任何更改。

在 CV 變量的整個更新過程中保持互斥鎖鎖定以及相反的信號發送是有效處理的,因為消費者已經在互斥鎖和 CV 上成對注冊,並且直接發送 CV 信號將消費者放在等待列表中mutex 甚至一次都不激活線程。

但這只是效率低下,而不是邏輯錯誤。 而 Helgrind 僅將其報告為“可疑”,而不是錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM