boost :: thread断言的shared_ptr失败

时间:2014-06-25 06:25:54

标签: c++ multithreading boost smart-pointers boost-thread

class WIFITest
{
public:

  void StartTest();

  void Notify_Test(boost::shared_ptr<basic_msg> basic_msg, ID id );


private:
  void OpenStaMode_test();

private: 
  boost::shared_ptr<boost::thread> OpenStaMode_testThread;

  boost::shared_ptr<basic_msg> VMF_WIFI_NOTIFY_CLIENT_OPEN_MSG;  

  typedef boost::shared_ptr<boost::thread> THREAD;
  typedef boost::shared_ptr<basic_msg> MSG;
  std::map<ID,std::pair<THREAD,MSG>> map;
};  

void WIFITest::StartTest()
{ 
  map[ID::WIFI_REQ_CLIENT_OPEN] = std::make_pair(OpenStaMode_testThread,VMF_WIFI_NOTIFY_CLIENT_OPEN_MSG);

  this->OpenStaMode_testThread.reset(new boost::thread(&WIFITest::OpenStaMode_test,this));
  this->OpenStaMode_testThread->join();

}
void WIFITest::OpenStaMode_test()
{
  unsigned char strData[WIFI_SEND_BUF_SIZE_MIN];
  sendOpenReq(strData);
  try { 
    boost::this_thread::sleep(boost::posix_time::seconds(8));
  }
  catch(const boost::thread_interrupted&) {   

        std::cout<<"OpenStaMode_test success@ \n";

      }
    else {
        goto OpenStaMode_test_fail;
      }

    return;

  }
OpenStaMode_test_fail:
  printf("@WIFITest::OpenStaMode_test FAIL@@@@@@@@@@@@@@ \n");

}

void WIFITest::Notify_Test(boost::shared_ptr<basic_msg> basic_msg, ID id)
{
  map[id].second = basic_msg;

   map[id].first->interrupt();
  printf("@WIFITest::INTERRUPTED @@@@@@@@@@@@@@ \n");

}

第一个main将创建StartTest实例并调用StartTest(), 当其他代码调用Notify_Test时,“map [id] .first-&gt; interrupt();”这句话会产生以下断言失败,并使程序崩溃。

TestWIFI:../../ boost_1_55_0/boost/smart_ptr/shared_ptr.hpp:653:typename boost :: detail :: sp_member_access :: type boost :: shared_ptr :: operator-&gt;()const [with T = boost :: thread,typename boost :: detail :: sp_member_access :: type = boost :: thread *]:断言`px!= 0'失败。

1 个答案:

答案 0 :(得分:1)

这一行:

map[ID::WIFI_REQ_CLIENT_OPEN] = std::make_pair(OpenStaMode_testThread,VMF_WIFI_NOTIFY_CLIENT_OPEN_MSG);

OpenStaMode_testThread的副本存储到地图中,此时此副本为空。

然后您在reset(new boost::thread(&WIFITestSuite::OpenStaMode_test,this))上致电OpenStaMode_testThread,但这不会影响已存储到地图中的副本。

因此,当您调用map[id].first->interrupt();时,您在空shared_ptr上调用它,导致断言失败。


如下所述,如果在线程开始执行之后但在Notify_Test上的reset()调用之前调用shared_ptr,则会发生class WIFITest { public: /* ... */ private: /* ... */ private: boost::mutex mutex_; /* ... */ }; void WIFITest::StartTest() { { boost::lock_guard<boost::mutex> guard(mutex_); // Takes ownership of the mutex map[ID::WIFI_REQ_CLIENT_OPEN] = std::make_pair(THREAD(), VMF_WIFI_NOTIFY_CLIENT_OPEN_MSG); map[ID::WIFI_REQ_CLIENT_OPEN].first.reset(new boost::thread(&WIFITest::OpenStaMode_test,this)); // At this point the thread has started and the pointer has been stored into the map } // guard is destructed and mutex released here // so that we don't hold the mutex while waiting // for the thread to finish. map[ID::WIFI_REQ_CLIENT_OPEN].first->join(); } /* ... */ void WIFITest::Notify_Test(boost::shared_ptr<basic_msg> basic_msg, ID id) { boost::lock_guard<boost::mutex> guard(mutex_); // Takes ownership of the mutex map[id].second = basic_msg; map[id].first->interrupt(); printf("@WIFITest::INTERRUPTED @@@@@@@@@@@@@@ \n"); } 的调用。地图。要解决此问题,请使用互斥锁:

{{1}}