एक बड़े प्रोग्राम का निम्न न्यूनतम कोड नमूना क्लाइंट थ्रेड से कमांड को एक asio io_service ऑब्जेक्ट में भेजता है। Io_service ऑब्जेक्ट (आईओएस कक्षा में) एक थ्रेड के साथ चलाया जा रहा है। जब आदेश भेजा जाता है तो क्लाइंट थ्रेड तब तक प्रतीक्षा करता है जब तक इसे आईओएस ऑब्जेक्ट (सीएमडी :: नोटिफ़ाईफिशिश() के माध्यम से अधिसूचित किया जाता है) द्वारा अधिसूचित किया जाता है।बूस्ट कंडीशन वेरिएबल इश्यू
यह नमूना लिनक्स उबंटू 11.04 पर 1.46 जुर्माना के साथ चल रहा है लेकिन विंडोज 7 पर 1.46 पर जोर देता है।
मुझे संदेह है कि यह सीएमडी :: NotifyFinish() में लॉक के साथ कुछ करना है। जब मैं नेस्टेड स्कोप से लॉक को स्थानांतरित करता हूं ताकि जब प्रतीक्षा करें कैंडीशन Variable_.notify_one() को लॉक के दायरे में बुलाया जाता है तो यह विंडोज 7 पर क्रैश नहीं होता है। हालांकि, बूस्ट :: थ्रेड प्रलेखन में कहा गया है कि notify_one() की आवश्यकता नहीं है लॉक के भीतर बुलाया जाना है।
स्टैक ट्रेस (नीचे) दिखाता है कि यह notify_one() कहा जाता है जब यह जोर दे रहा है। ऐसा लगता है कि सूचित करने से पहले cmd ऑब्जेक्ट गायब हो गया है ...
मैं इस थ्रेड को सुरक्षित कैसे बना सकता हूं और जोर नहीं दे सकता?
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/bind.hpp>
#include <iostream>
class Cmd
{
public:
Cmd() : cnt_(0), waitPred_(false), waiting_(false)
{
}
virtual ~Cmd()
{
}
void BindInfo(int CmdSeq)
{
cnt_ = CmdSeq;
}
void NotifyFinish()
{
// call by service thread...
{
boost::mutex::scoped_lock lock(waitMutex_);
waitPred_ = true;
if (!waiting_)
{
// don't need to notify as isn't waiting
return;
}
}
waitConditionVariable_.notify_one();
}
void Wait()
{
// called by worker threads
boost::mutex::scoped_lock lock(waitMutex_);
waiting_ = true;
while (!waitPred_)
waitConditionVariable_.wait(lock);
}
int cnt_;
private:
boost::mutex waitMutex_;
boost::condition_variable waitConditionVariable_;
bool waitPred_;
bool waiting_;
};
class Ios
{
public:
Ios() : timer_(ios_), cnt_(0), thread_(boost::bind(&Ios::Start, this))
{
}
void Start()
{
timer_.expires_from_now(boost::posix_time::seconds(5));
timer_.async_wait(boost::bind(&Ios::TimerHandler, this, _1));
ios_.run();
}
void RunCmd(Cmd& C)
{
ios_.post(boost::bind(&Ios::RunCmdAsyn, this, boost::ref(C)));
}
private:
void RunCmdAsyn(Cmd& C)
{
C.BindInfo(cnt_++);
C.NotifyFinish();
}
void TimerHandler(const boost::system::error_code& Ec)
{
if (!Ec)
{
std::cout << cnt_ << "\n";
timer_.expires_from_now(boost::posix_time::seconds(5));
timer_.async_wait(boost::bind(&Ios::TimerHandler, this, _1));
}
else
exit(0);
}
boost::asio::io_service ios_;
boost::asio::deadline_timer timer_;
int cnt_;
boost::thread thread_;
};
static Ios ios;
void ThreadFn()
{
while (1)
{
Cmd c;
ios.RunCmd(c);
c.Wait();
//std::cout << c.cnt_ << "\n";
}
}
int main()
{
std::cout << "Starting\n";
boost::thread_group threads;
const int num = 5;
for (int i = 0; i < num; i++)
{
// Worker threads
threads.create_thread(ThreadFn);
}
threads.join_all();
}
स्टैक ट्रेस
msvcp100d.dll!std::_Debug_message(const wchar_t * message, const wchar_t * file, unsigned int line) Line 15 C++
iosthread.exe!std::_Vector_const_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > >::_Compat(const std::_Vector_const_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > > & _Right) Line 238 + 0x17 bytes C++
iosthread.exe!std::_Vector_const_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > >::operator==(const std::_Vector_const_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > > & _Right) Line 203 C++
iosthread.exe!std::_Vector_const_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > >::operator!=(const std::_Vector_const_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > > & _Right) Line 208 + 0xc bytes C++
iosthread.exe!std::_Debug_range2<std::_Vector_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > > >(std::_Vector_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > > _First, std::_Vector_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > > _Last, const wchar_t * _File, unsigned int _Line, std::random_access_iterator_tag __formal) Line 715 + 0xc bytes C++
iosthread.exe!std::_Debug_range<std::_Vector_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > > >(std::_Vector_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > > _First, std::_Vector_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > > _Last, const wchar_t * _File, unsigned int _Line) Line 728 + 0x6c bytes C++
iosthread.exe!std::find_if<std::_Vector_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > >,bool (__cdecl*)(boost::intrusive_ptr<boost::detail::basic_cv_list_entry> const &)>(std::_Vector_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > > _First, std::_Vector_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > > _Last, bool (const boost::intrusive_ptr<boost::detail::basic_cv_list_entry> &)* _Pred) Line 92 + 0x54 bytes C++
iosthread.exe!std::remove_if<std::_Vector_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > >,bool (__cdecl*)(boost::intrusive_ptr<boost::detail::basic_cv_list_entry> const &)>(std::_Vector_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > > _First, std::_Vector_iterator<std::_Vector_val<boost::intrusive_ptr<boost::detail::basic_cv_list_entry>,std::allocator<boost::intrusive_ptr<boost::detail::basic_cv_list_entry> > > > _Last, bool (const boost::intrusive_ptr<boost::detail::basic_cv_list_entry> &)* _Pred) Line 1848 + 0x58 bytes C++
iosthread.exe!boost::detail::basic_condition_variable::notify_one() Line 267 + 0xb4 bytes C++
iosthread.exe!Cmd::NotifyFinish() Line 41 C++
प्रतिकृति –