1. 程式人生 > >boost官方文件中聊天程式連續發包崩潰問題

boost官方文件中聊天程式連續發包崩潰問題

  1. void do_write(chat_message msg)  
  2.   {  
  3.     bool write_in_progress = !write_msgs_.empty(); //空的話變數為false
  4.     write_msgs_.push_back(msg); //把要寫的資料push至寫佇列
  5.     if (!write_in_progress)//佇列初始為空 push一個msg後就有一個元素了
  6.     {  
  7.       boost::asio::async_write(socket_,  
  8.           boost::asio::buffer(write_msgs_.front().data(),  
  9.             write_msgs_.front().length()),  
  10.           boost::bind(&chat_client::handle_write, this,   
  11.             boost::asio::placeholders::error));  
  12.     }  
  13.   }  
  14.   void handle_write(const boost::system::error_code& error)//第一個訊息單獨處理,剩下的才更好操作
  15.   {  
  16.     if (!error)  
  17.     {  
  18.       write_msgs_.pop_front();//剛才處理完一個數據 所以要pop一個
  19.       if (!write_msgs_.empty())    
  20.       {  
  21.         boost::asio::async_write(socket_,  
  22.             boost::asio::buffer(write_msgs_.front().data(),  
  23.               write_msgs_.front().length()),  
  24.             boost::bind(&chat_client::handle_write, this,  
  25.               boost::asio::placeholders::error)); //迴圈處理剩餘的訊息
  26.       }  
  27.     }  
每次傳送訊息都是呼叫do_write函式,write_msgs_是儲存訊息的佇列。表面上看是沒有什麼問題。但是當你連續呼叫這個函式的時候就會出現問題。因為頻繁呼叫和各種對調函式。會出現write_msgs_.front()中write_msgs_佇列為空崩潰。目前解決方法是加鎖。確保pop_front()、push_back()函式不出現連續呼叫使front()函式呼叫崩潰問題。我不知道又沒用更好的辦法。希望大家能給我更好的意見,下面是我的原始碼: void do_write(Message_Base msg)
{
boost::mutex::scoped_lock lock(mtx);
if (msg.data() !=NULL )
write_msgs_.push_back(msg); //把要寫的資料push至寫佇列  


if (!write_msgs_.empty())//佇列初始為空 push一個msg後就有一個元素了  
{
Message_Base Info = write_msgs_.front();
boost::asio::async_write(socket_,
boost::asio::buffer(Info.data(),
Info.length()),
boost::bind(&chat_client::handle_write, this,
boost::asio::placeholders::error));
}
}


void handle_write(const boost::system::error_code& error)//第一個訊息單獨處理,剩下的才更好操作  
{
boost::mutex::scoped_lock lock(mtx);
if (!error)
{
if (!write_msgs_.empty())
write_msgs_.pop_front();//剛才處理完一個數據 所以要pop一個  
if (!write_msgs_.empty())
{
Message_Base Info = write_msgs_.front();
boost::asio::async_write(socket_,
boost::asio::buffer(Info.data(),
Info.length()),
boost::bind(&chat_client::handle_write, this,
boost::asio::placeholders::error)); //迴圈處理剩餘的訊息  
}
}
else
{
if (m_pCallBackTimeOut)
m_pCallBackTimeOut(RESULT_ERROR, (char*)error.message().c_str());
do_close();
}
}