Bu benim uygulamada sorunu yeniden nispeten basit bir programdır: Ben Linux makine çalıştırdığınızdaUygunsuz konu içeriğinde shared_ptr'yi yok etmekten nasıl kaçınabilirsiniz?
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/noncopyable.hpp>
#include <boost/thread.hpp>
#include <chrono>
#include <functional>
#include <iostream>
#include <memory>
class worker : boost::noncopyable {
public:
explicit worker(boost::asio::io_service& io);
~worker();
void just_do_it(const std::function<void()>& when_done);
private:
boost::asio::io_service& io_;
boost::asio::io_service worker_io_;
boost::thread thread_;
};
worker::worker(boost::asio::io_service& io)
: io_(io)
{
thread_ = boost::thread([this] {
boost::asio::io_service::work my_work(worker_io_);
worker_io_.run();
});
}
worker::~worker()
{
worker_io_.stop();
std::clog << "join...\n";
thread_.join();
}
void worker::just_do_it(const std::function<void()>& when_done)
{
worker_io_.post([this, when_done] {
io_.post(when_done);
boost::asio::steady_timer(worker_io_, std::chrono::seconds(1)).wait();
});
}
int main()
{
boost::asio::io_service io;
boost::asio::steady_timer timer(io, std::chrono::seconds(5));
timer.async_wait(std::bind([] { std::clog << "terminating...\n"; }));
{
auto my_worker = std::make_shared<worker>(io);
my_worker->just_do_it([my_worker] {
std::clog << "did it\n";
my_worker->just_do_it([my_worker] {
std::clog << "did it second time\n";
// now my_worker is not needed and we allow it to die
});
});
}
io.run();
}
görüyorum:
Çünkü shared_ptr ait çöküyordid it
did it second time
join...
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::thread_resource_error> >'
what(): boost thread: trying joining itself: Resource deadlock avoided
Aborted
worker` içinde işçi yıkıcı çağırır s iş parçacığı. Bunu şu şekilde düzeltebilirim: Ancak bu bir el ile nesne ömrü yönetimi. Yeni ve silme kullanmaktan çok daha iyi değil. Bunu önlemek için herhangi bir yolu var mı?
Daha sonra iş parçacığına katılmak istiyorsun, değil mi? Yani bunun dışındaki iş parçacığına bir sapa ihtiyacınız var. –
İş parçacığı işçi sınıfı üye değişkenlerini kullanabilir, bu yüzden işçinin imha edilmesinden önce durdurmam gerekir. –
Çözümünüz, sorunlu kodunuzdan daha az otomatik değil, yalnızca işaretçi yok edildiğinde (ve örneğin istisnalarla ilgili olarak 'new'/'delete' el kitabından daha iyi olduğunda) değiştiniz; Başka bir çözümle gelebilirsiniz ama sağladığınız en kolayı IMO gibi görünüyor. – piwi