gpt4 book ai didi

c++ - 新的 boost::thread 导致对象析构函数被调用的次数超过预期?

转载 作者:太空狗 更新时间:2023-10-29 20:35:11 25 4
gpt4 key购买 nike

下面发布的代码的奇怪行为导致对象析构函数被调用不止一次。虽然代码不会因此崩溃,但我只是想找出为什么会发生这种行为。这是一个非常简单的普通程序模板,可能被 Boost 领域的许多人使用,但直到现在我才注意到这种行为。

#include <boost/thread.hpp>
#include <iostream>

class object
{
private:

int value;

public:

object();
~object();
void pass( int value);
};

object::object()
{
std::cout<<"constructing object: "<<this<<" with value: "<<this->object::value<<std::endl;
}
object::~object()
{
std::cout<<"destructing object: "<<this<<" with value: "<<this->object::value<<std::endl;
}
void object::pass( int value)
{
this->object::value = value;
std::cout<<"value passed is: "<<this->object::value<<std::endl;
}

class threaded
{
private:

object A;

public:

threaded();
~threaded();
void init( int value);
};
threaded::threaded(){}
threaded::~threaded(){}
void threaded::init( int value)
{
this->threaded::A.pass( value);
}

int main()
{
threaded T;
int unlucky_number = 13;

boost::thread_group tg;

tg.add_thread( new boost::thread( boost::bind( &threaded::init, T, unlucky_number)));

tg.join_all();

return 0;
}

这是代码输出。

constructing object: 0x7ffcb53157f0 with value: 0

destructing object: 0x7ffcb53156d0 with value: 0 <----From here?
destructing object: 0x7ffcb5315720 with value: 0
destructing object: 0x7ffcb53157a0 with value: 0
destructing object: 0x7ffcb5315780 with value: 0
destructing object: 0x7ffcb5315710 with value: 0
destructing object: 0x7ffcb53157c0 with value: 0
destructing object: 0x7ffcb5315820 with value: 0
destructing object: 0x7ffcb5315800 with value: 0 <----To here?

value passed is: 13
destructing object: 0x1a5f2d8 with value: 13
destructing object: 0x7ffcb53157f0 with value: 0

在第一个构造之后和 value passed is: 13 行之前销毁的对象一定是由 boost 线程库中的复制构造函数以某种方式创建的,但是为什么它们从未被 build ,为什么没有崩溃?另外,它们的值始终为零,所以它不是垃圾内存……有什么想法吗?

因此应 G.M. 的要求。我试图创建复制构造函数只是为了在 error_code.hpp 中获取与 boost 相关的错误。

这是新代码加上编译时出现的错误。

#include <boost/thread.hpp>
#include <iostream>

class object
{
private:

int value;

public:

object();
object( object const &copy_this);
~object();
void pass( int value);
};

object::object()
{
std::cout<<"constructing object: "<<this<<" with value: "<<this->object::value<<std::endl;
}
object::object( object const &copy_this)
{
std::cout<<"object copy constructor. "<<std::endl;
this->object::value = copy_this.value;
}
object::~object()
{
std::cout<<"destructing object: "<<this<<" with value: "<<this->object::value<<std::endl;
}
void object::pass( int value)
{
this->object::value = value;
std::cout<<"value passed is: "<<this->object::value<<std::endl;
}

class threaded
{
private:

object A;

public:

threaded();
threaded( threaded const &copy_this);
~threaded();
void init( int value);
};
threaded::threaded(){}
threaded::threaded( threaded const &copy_this)
{
std::cout<<"threaded copy constructor. "<<std::endl;
this->threaded::A = copy_this.A;
}
threaded::~threaded(){}
void threaded::init( int value)
{
this->threaded::A.pass( value);
}

int main()
{
threaded T;
int unlucky_number = 13;

boost::thread_group tg;

tg.add_thread( new boost::thread( boost::bind( &threaded::init, T, unlucky_number)));

tg.join_all();
//T.init(13);

return 0;
}

||=== Build: Debug in boost_thread_destructor_problem (compiler: GNU GCC Compiler) ===|
obj/Debug/boost_thread_destructor_problem.o||In function `__static_initialization_and_destruction_0(int, int)':|
/usr/include/boost/system/error_code.hpp|221|undefined reference to `boost::system::generic_category()'|
/usr/include/boost/system/error_code.hpp|222|undefined reference to `boost::system::generic_category()'|
/usr/include/boost/system/error_code.hpp|223|undefined reference to `boost::system::system_category()'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::thread_exception::thread_exception(int, char const*)':|
/usr/include/boost/thread/exceptions.hpp|51|undefined reference to `boost::system::system_category()'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::condition_error::condition_error(int, char const*)':|
/usr/include/boost/thread/exceptions.hpp|84|undefined reference to `boost::system::system_category()'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::detail::thread_data_base::thread_data_base()':|
/usr/include/boost/thread/pthread/thread_data.hpp|152|undefined reference to `vtable for boost::detail::thread_data_base'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::detail::interruption_checker::interruption_checker(pthread_mutex_t*, pthread_cond_t*)':|
/usr/include/boost/thread/pthread/thread_data.hpp|195|undefined reference to `boost::detail::get_current_thread_data()'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::thread::start_thread()':|
/usr/include/boost/thread/detail/thread.hpp|179|undefined reference to `boost::thread::start_thread_noexcept()'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::thread::~thread()':|
/usr/include/boost/thread/detail/thread.hpp|254|undefined reference to `boost::thread::detach()'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::thread::get_id() const':|
/usr/include/boost/thread/detail/thread.hpp|741|undefined reference to `boost::thread::native_handle()'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::thread::join()':|
/usr/include/boost/thread/detail/thread.hpp|767|undefined reference to `boost::thread::join_noexcept()'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::condition_variable::wait(boost::unique_lock<boost::mutex>&)':|
/usr/include/boost/thread/pthread/condition_variable.hpp|84|undefined reference to `boost::this_thread::interruption_point()'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::shared_mutex::lock_shared()':|
/usr/include/boost/thread/pthread/shared_mutex.hpp|186|undefined reference to `boost::this_thread::disable_interruption::disable_interruption()'|
/usr/include/boost/thread/pthread/shared_mutex.hpp|186|undefined reference to `boost::this_thread::disable_interruption::~disable_interruption()'|
/usr/include/boost/thread/pthread/shared_mutex.hpp|186|undefined reference to `boost::this_thread::disable_interruption::~disable_interruption()'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::shared_mutex::lock()':|
/usr/include/boost/thread/pthread/shared_mutex.hpp|287|undefined reference to `boost::this_thread::disable_interruption::disable_interruption()'|
/usr/include/boost/thread/pthread/shared_mutex.hpp|287|undefined reference to `boost::this_thread::disable_interruption::~disable_interruption()'|
/usr/include/boost/thread/pthread/shared_mutex.hpp|287|undefined reference to `boost::this_thread::disable_interruption::~disable_interruption()'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::thread_group::join_all()':|
/usr/include/boost/thread/detail/thread_group.hpp|117|undefined reference to `boost::thread::joinable() const'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf1<void, threaded, int>, boost::_bi::list2<boost::_bi::value<threaded>, boost::_bi::value<int> > > >::thread_data(boost::_bi::bind_t<void, boost::_mfi::mf1<void, threaded, int>, boost::_bi::list2<boost::_bi::value<threaded>, boost::_bi::value<int> > >)':|
/usr/include/boost/thread/detail/thread.hpp|109|undefined reference to `boost::detail::thread_data_base::~thread_data_base()'|
obj/Debug/boost_thread_destructor_problem.o||In function `boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf1<void, threaded, int>, boost::_bi::list2<boost::_bi::value<threaded>, boost::_bi::value<int> > > >::~thread_data()':|
/usr/include/boost/thread/detail/thread.hpp|90|undefined reference to `boost::detail::thread_data_base::~thread_data_base()'|
/usr/include/boost/thread/detail/thread.hpp|90|undefined reference to `boost::detail::thread_data_base::~thread_data_base()'|
obj/Debug/boost_thread_destructor_problem.o:(.rodata._ZTIN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf1Iv8threadediEENS2_5list2INS2_5valueIS6_EENS9_IiEEEEEEEE[_ZTIN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf1Iv8threadediEENS2_5list2INS2_5valueIS6_EENS9_IiEEEEEEEE]+0x10)||undefined reference to `typeinfo for boost::detail::thread_data_base'|
||error: ld returned 1 exit status|
||=== Build failed: 24 error(s), 0 warning(s) (0 minute(s), 2 second(s)) ===|

最佳答案

由于您调用 boost::bind 的方式...

tg.add_thread(new boost::thread(boost::bind(&threaded::init, T, unlucky_number)));

T 将按值传递。这可能导致 boost::bind 实现执行任意数量的 T 复制。

因为您知道 T 在这种情况下会比使用它的线程长寿,您可以强制通过引用传递...

tg.add_thread(new boost::thread(boost::bind(&threaded::init, boost::ref(T), unlucky_number)));

或者传递一个指针...

tg.add_thread(new boost::thread(boost::bind(&threaded::init, &T, unlucky_number)));

关于c++ - 新的 boost::thread 导致对象析构函数被调用的次数超过预期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44097871/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com