2011-08-06 23 views
0

マルチスレッドサーバーの作成に問題があります。私はサーバーからクライアントを削除する必要があるまで、すべてうまく動作します。Boost ::スレッドのアクセス違反が発生した場合join

サーバーは独自のスレッドで実行され、各クライアントには独自のスレッドもあります。

私はすべてのスレッドにboost :: threadを使用しています。私はライン

shutdown(mSocket,2); 

にブレークポイントを追加する

void StopClient() 
{ 
    assert(mThread); 

    mStopMutex.lock(); 
    mStopRequested = true; 
    mStopMutex.unlock(); 

    shutdown(mSocket,2); 

    mThread->join(); 
} 

呼び出すクライアントを停止する必要があるとき、私はmThreadが存在しないことを見ることができます!これはスレッドが既に終了していることを意味しますか?あなたは常にブースト::スレッドのためにjoin()を呼び出す必要がありますか?

コードを実行できるようにすると、アクセス違反エラーが発生します。

更新

ServerThread

void StartServer() 
{ 
    assert(!mListenThread); 
    mListenThread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&ServerThread::Listen, this))); 
    mUpdateThread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&ServerThread::Update, this))); 
} 

void StopServer() 
{ 
    assert(mListenThread); 
    mStopRequested = true; 

      mMutex.lock(); 
      for(int i = 0; i < mClients.size(); i++) 
       mClients[i]->StopClient(); 
      mMutex.unlock(); 

    mListenThread->join(); 
} 

void Listen() 
{ 
    while (!mStopRequested) 
    { 
     std::cout << "Waiting for connection" << std::endl;   
     if(mClientSocket = accept(mServerSocket, (sockaddr*) &mServerAddr, &addrlen)) 
     { 
      mMutex.lock(); 
      if(mClients.size() > 0) 
      { 
       for(int i = 0; i < mClients.size(); i++) 
       { 
        if(mClients[i]->getClientSocket() != mClientSocket) 
        { 
         ClientThread newClient; 
         newClient.Initialise(mClientSocket); 
         mClients.push_back(&newClient); 
         mClients[mClients.size()-1]->StartClient(); 
         break; 
        } 
       } 
      } 
      else 
      { 
       ClientThread newClient; 
       newClient.Initialise(mClientSocket); 
       mClients.push_back(&newClient); 
       mClients[mClients.size()-1]->StartClient(); 
      } 
      mMutex.unlock(); 
     } 
    } 
}   

void Update() 
{ 
    while (!mStopRequested) 
    { 
     mMutex.lock(); 

     std::cout << "::::Server is updating!::::" << mClients.size() << std::endl; 
     for(int i = 0; i< mClients.size(); i++) 
     { 
      if(!mClients[i]->IsActive()) 
      { 
       mClients[i]->StopClient(); 
       mClients.erase(mClients.begin() + i); 
      } 
     } 

     mMutex.unlock(); 

    } 
} 

ClientThread

void StartClient() 
{ 
    assert(!mThread); 
    mThread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&ClientThread::Update, this))); 
} 

void Update() 
{ 
    bool stopRequested; 
    do 
    { 
     mStopMutex.lock(); 
     stopRequested = mStopRequested; 
     mStopMutex.unlock(); 

     std::cout << "lol" << std::endl; 
     if(mTimeOut < 1000) 
     { 
      mTimeOut++; 
     } 
     else 
     { 
      mActive = false; 
     } 

     boost::this_thread::interruption_point(); 
    } 
    while(!stopRequested); 
} 
+4

より多くのコードを表示する必要があります。 'mThread'はどこで設定されていますか?他にどこが使われていますか? –

+1

"mThreadは存在しません"とはどういう意味ですか? NULLか、削除されたオブジェクトを指していますか? – mmmmmmmm

+0

返信いただきありがとうございます。私はいくつかのコードを表示するように更新しました! @Rüdigerは削除されたオブジェクトを指しているだけです。 – kiwijus

答えて

1
  ClientThread newClient; 
      newClient.Initialise(mClientSocket); 
      mClients.push_back(&newClient); 

これは、スタック上のローカル変数を作成し、mClientsのあなたのリストにそれのアドレスを置きます。スコープが終了し、ローカル変数も終了します。これであなたのリストmClientsはもう存在しないものを指しています。

+0

それは良い点です! コードを に変更しました。 'ClientThread * newClient = new ClientThread(); newClient-> Initialize(mClientSocket); mClients.push_back(newClient); ' これで機能します! :)ありがとう! – kiwijus

0

あり、十分なコードが起こっている正確に何を決定するためにここではないのですが、ここで確認するためのものです:

    は、
  • クライアントスレッド内にmStopRequestedメンバーをチェックしている処理ループがある可能性があります。処理ループが終了する前に、mThreadメンバを変更していますか?
  • アクセス違反が発生したら、mThreadはNULLですか?それとも、他の価値ですか? mStopRequestedをtrueに設定する前に有効ですか?
関連する問題