簡體   English   中英

使用Boost.Asio的意外變量值

[英]Unexpected variable value using Boost.Asio

我從boost.asio項目中發現了一些奇怪的問題。 所以我做了一個示例控制台項目,發生了同樣的問題。

這是代碼:

class server
{
public:
    server()
        : m_acceptor(m_ios)
    {
        m_work.reset(new boost::asio::io_service::work(m_ios));
        m_thread = boost::thread(boost::bind(&boost::asio::io_service::run, &m_ios));
    }

    virtual ~server()
    {
        m_work.reset();
        m_ios.stop();
        m_thread.join();
    }

    void do_test()
    {
        m_ios.post(boost::bind(&server::handle_test, this));
    }

private:
    void handle_test()
    {
        m_value = 1234;
        printf("server::handle_test() -> m_value %d.\n", m_value);
    }

    boost::shared_ptr<boost::asio::io_service::work> m_work;
    boost::asio::io_service m_ios;
    boost::thread m_thread;
    boost::asio::ip::tcp::acceptor m_acceptor;

public:
    int m_value;
};


void main()
{
    server s;
    s.do_test();

    _getch(); // wait for a while
    printf("main() -> m_value is %d.\n", s.m_value);

    _getch();
}

好。 因此,使用此代碼,控制台輸出將是:

server :: handle_test()-> m_value為1234。

main()-> m_value是1234。

按任意鍵繼續 。

對??

但是奇怪的是,實際的控制台輸出是:

server :: handle_test()-> m_value為1234。

main()-> m_value為0。

按任意鍵繼續 。

為什么???

有誰能解釋這個嗎? 我該如何從根本上解決它?

這是整個項目文件和exe。 https://www.dropbox.com/s/cflcmbuwgab1rxb/boost_asio_test.zip?dl=0

[測試環境]

Windows Embedded 8.1 Industry Pro x64

與Visual Studio 2013一起編譯(VisualStudioVersion 12.0.31101.0)

您不同步從多個線程對共享數據的訪問。

這是數據競賽。

數據競爭是未定義的行為 什么都可能發生。

通過同步對m_value訪問來修復它

更新

啟用線程清理程序(gcc / clang上為-fsanitizer=thread )時,您會獲得有關Live On Coliru的非常具體的報告

==================
WARNING: ThreadSanitizer: data race (pid=27230)
Read of size 4 at 0x7fff488eb360 by main thread:
    #0 main /tmp/test.cpp:57 (test+0x0000004e2d82)

Previous write of size 4 at 0x7fff488eb360 by thread T1:
    #0 server::handle_test() /tmp/test.cpp:36 (test+0x00000051259c)
    #1 boost::_mfi::mf0<void, server>::operator()(server*) const /home/sehe/custom/boost/boost/bind/mem_fn_template.hpp:49 (test+0x00000051741e)
    #2 void boost::_bi::list1<boost::_bi::value<server*> >::operator()<boost::_mfi::mf0<void, server>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf0<void, server>&, boost::_bi::list0&, int) /home/sehe/custom/boost/boost/bind/bind.hpp:255 (test+0x00000051705a)
    #3 boost::_bi::bind_t<void, boost::_mfi::mf0<void, server>, boost::_bi::list1<boost::_bi::value<server*> > >::operator()() /home/sehe/custom/boost/boost/bind/bind.hpp:895 (test+0x000000516cbf)
    #4 void boost::asio::asio_handler_invoke<boost::_bi::bind_t<void, boost::_mfi::mf0<void, server>, boost::_bi::list1<boost::_bi::value<server*> > > >(boost::_bi::bind_t<void, boost::_mfi::mf0<void, server>, boost::_bi::list1<boost::_bi::value<server*> > >&, ...) /home/sehe/custom/boost/boost/asio/handler_invoke_hook.hpp:69 (test+0x000000516a35)
    #5 void boost_asio_handler_invoke_helpers::invoke<boost::_bi::bind_t<void, boost::_mfi::mf0<void, server>, boost::_bi::list1<boost::_bi::value<server*> > >, boost::_bi::bind_t<void, boost::_mfi::mf0<void, server>, boost::_bi::list1<boost::_bi::value<server*> > > >(boost::_bi::bind_t<void, boost::_mfi::mf0<void, server>, boost::_bi::list1<boost::_bi::value<server*> > >&, boost::_bi::bind_t<void, boost::_mfi::mf0<void, server>, boost::_bi::list1<boost::_bi::value<server*> > >&) /home/sehe/custom/boost/boost/asio/detail/handler_invoke_helpers.hpp:37 (test+0x0000005167e0)
    #6 boost::asio::detail::completion_handler<boost::_bi::bind_t<void, boost::_mfi::mf0<void, server>, boost::_bi::list1<boost::_bi::value<server*> > > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) /home/sehe/custom/boost/boost/asio/detail/completion_handler.hpp:68 (test+0x0000005162b7)
    #7 boost::asio::detail::task_io_service_operation::complete(boost::asio::detail::task_io_service&, boost::system::error_code const&, unsigned long) /home/sehe/custom/boost/boost/asio/detail/task_io_service_operation.hpp:38 (test+0x000000532a63)
    #8 boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>&, boost::asio::detail::task_io_service_thread_info&, boost::system::error_code const&) /home/sehe/custom/boost/boost/asio/detail/impl/task_io_service.ipp:372 (test+0x00000052db18)
    #9 boost::asio::detail::task_io_service::run(boost::system::error_code&) /home/sehe/custom/boost/boost/asio/detail/impl/task_io_service.ipp:149 (test+0x00000052721a)
    #10 boost::asio::io_service::run() /home/sehe/custom/boost/boost/asio/impl/io_service.ipp:59 (test+0x0000005266ce)
    #11 server::worker() /tmp/test.cpp:17 (test+0x000000518f19)
    #12 boost::_mfi::mf0<void, server>::operator()(server*) const /home/sehe/custom/boost/boost/bind/mem_fn_template.hpp:49 (test+0x00000051741e)
    #13 void boost::_bi::list1<boost::_bi::value<server*> >::operator()<boost::_mfi::mf0<void, server>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf0<void, server>&, boost::_bi::list0&, int) /home/sehe/custom/boost/boost/bind/bind.hpp:255 (test+0x00000051705a)
    #14 boost::_bi::bind_t<void, boost::_mfi::mf0<void, server>, boost::_bi::list1<boost::_bi::value<server*> > >::operator()() /home/sehe/custom/boost/boost/bind/bind.hpp:895 (test+0x000000516cbf)
    #15 boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf0<void, server>, boost::_bi::list1<boost::_bi::value<server*> > > >::run() /home/sehe/custom/boost/boost/thread/detail/thread.hpp:116 (test+0x00000051d5a9)
    #16 thread_proxy thread.cpp (libboost_thread.so.1.59.0+0x000000011aa9)

As if synchronized via sleep:
    #0 nanosleep <null> (test+0x000000475c10)
    #1 boost::this_thread::hiden::sleep_for(timespec const&) <null> (libboost_thread.so.1.59.0+0x000000012885)
    #2 void boost::this_thread::sleep_for<long, boost::ratio<1l, 1000l> >(boost::chrono::duration<long, boost::ratio<1l, 1000l> > const&) /home/sehe/custom/boost/boost/thread/v2/thread.hpp:112 (test+0x0000004e65fb)
    #3 main /tmp/test.cpp:56 (test+0x0000004e2b71)

Location is stack of main thread.

Thread T1 (tid=27234, running) created by main thread at:
    #0 pthread_create <null> (test+0x00000047aaf1)
    #1 boost::thread::start_thread_noexcept() <null> (libboost_thread.so.1.59.0+0x000000010ea9)
    #2 thread<boost::_bi::bind_t<void, boost::_mfi::mf0<void, server>, boost::_bi::list1<boost::_bi::value<server *> > > > /home/sehe/custom/boost/boost/thread/detail/thread.hpp:266 (test+0x000000519122)
    #3 server /tmp/test.cpp:13 (test+0x0000004e58b3)
    #4 main /tmp/test.cpp:53 (test+0x0000004e2855)

SUMMARY: ThreadSanitizer: data race /tmp/test.cpp:57 main
==================
server::handle_test() -> m_value 1234
main() -> m_value is 1234
ThreadSanitizer: reported 1 warnings

暫無
暫無

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

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