« マルチスレッド化と入力デバイス制御実装とソースコードの整理 | トップページ | 通信スレッドの構造がマズイらしい… »

2014年8月24日 (日)

スレッド起動までは出来たのですが

スレッドの起動、停止まで確認しました。

$ ./release/qtbrynhildr.exe
[ControlThread] start thread...
[GraphicsThread] start thread...
[SoundThread] start thread...
[ControlThread] stop thread...
[GraphicsThread] stop thread...
[SoundThread] stop thread...


通信の開始とデータ転送の確認をしようと思ったのですが、ちょっと気になったのでタスクマネージャを起動しながら、再度実行しました。

「うーん、CPU使用率が80%を超えている…」

レスポンスはいいのですが、システム全体としてこの重たさは頂けません。

どうやらQThreadの派生クラスのスレッド処理本体であるメソッドrun()が問題のようです。

Qtではネットワーク通信の処理は基本的に非同期でsignal/slotの仕組みを利用して実装できます。ですので、run()の中でやることは、最初の通信のオープンとクローズ処理だけで事実上あとはなにもしません。
ですので、こんな風にbusy loopにしてました。3つのスレッドがビジーループしていたのです。CPUの無駄遣いですね。
// thread
void NetThread::run()
{
  cout << "[" << name << "]" << " start thread..." << endl << flush;

  // busy loop
  while (!stopped){
	//
	if (startToConnect && !connected){
	  connected = connectToServer();
	  if (!connected){
		// failed to connect to server
		startToConnect = false;
		stopped = true;
	  }
	}
  } // busy loop

  // stopped == true

  // close connection
  if (connected){
	disconnectToServer();
  }

  // clear flag
  stopped = false;

  cout << "[" << name << "]" << " stop thread..." << endl << flush;
}


そこで、ビジーループの中でThreadをsleepさせて、CPUを解放するようにしました。これによりCPU使用率は数%まで落ちました。

// thread
void NetThread::run()
{
  cout << "[" << name << "]" << " start thread..." << endl << flush;

  // busy loop
  while (!stopped){
	//
	if (startToConnect && !connected){
	  connected = connectToServer();
	  if (!connected){
		// failed to connect to server
		startToConnect = false;
		stopped = true;
	  }
	}

	// thread sleep
	msleep(QTB_NETTHREAD_SLEEP_TIME); //  <= ここでsleepする
  } // busy loop

  // stopped == true

  // close connection
  if (connected){
	disconnectToServer();
  }

  // clear flag
  stopped = false;

  cout << "[" << name << "]" << " stop thread..." << endl << flush;
}

ただし、0.5(s)ほどsleepさせるので、Threadの終了(stopppedフラグのチェック)まで最大0.5(s)ほど掛かり、結果3つのスレッドを停止するのに最大1.5(s)ほど掛かるようになりました。ま、起動中のシステムの重さに比べれば終了時の少しのモタツキくらいはいいかなと判断しました。

さて、やっとデータ転送の確認に入れます…

« マルチスレッド化と入力デバイス制御実装とソースコードの整理 | トップページ | 通信スレッドの構造がマズイらしい… »

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: スレッド起動までは出来たのですが:

« マルチスレッド化と入力デバイス制御実装とソースコードの整理 | トップページ | 通信スレッドの構造がマズイらしい… »