SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Windowsアプリケーションで「処理中」を表現する

時間のかかる処理で「処理中」を表現する(後編)

Windowsアプリケーションで処理中を表現する様々な方法

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード WaitSample_2.zip (137.4 KB)

 本連載では、C++とWin32 APIを利用して「(応答なし)」を表示せずに長い時間作業を行うための方法を、2回に分けて紹介します。前編では、古くから伝わる伝統的手法を用いて、応答なしにならない方法を紹介しました。後編となる今回は、最新技法を用いて応答なしにならない方法を紹介します。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 前編では、16bitOSだった時代から伝わる伝統的な手法(メッセージポンプ)を紹介しました。反応が鈍いと感じはするものの、同時に複数の処理を実行する手段を持たなかった時代だったため、不自由しているという感覚はありませんでした。しかし、そのような時代は既に歴史の1ページに過ぎず、32bit(あるいは64bit)OSの現在では、こういった処理はそれぞれ別に実行し、同時に処理するマルチスレッドを利用するのがよいとされています。

 後編となる今回は、マルチスレッドを利用し、時間のかかる処理とメッセージの処理の2つを効率よく行う方法のいくつかを紹介したいと思います。

対象読者

  • C++でWindowsアプリケーションのプログラム開発経験がある開発者

必要な環境

  • Visual C++ 2010 Express Editionまたはそれ以上のエディションがインストールされた環境

どの処理をメインスレッドに残すか

 マルチスレッド化するとき、最初に考える問題がどの処理を別のスレッドに移動するかというものです。前編でも触れたようにWindowsは、メッセージ処理を適切に行うことをプログラムに要求しています。そして、ほぼ例外なくGUIアプリはメインスレッドにメッセージループを持ちます。そのため、メインスレッドは必ずメッセージを処理する必要があります。結果論ではありますが、メッセージ処理を必要としない処理を別スレッドに持っていくということが半ば必然となります。

 最初は究極的なマルチスレッド化です。このサンプルのように時間がかかる作業であってもその終了を待つ必要がなければ有効です。

体験スレッド編 - 単純別スレッド
#include <process.h>
unsigned __stdcall BusyLoopThProcEx( void* param )
{
  DWORD dwTime = *static_cast( param );

  DWORD dwStart = GetTickCount();
  while( (GetTickCount()-dwStart) < dwTime );
  return 0;
}
void ThreadBusyLoopNoWait( DWORD dwTime )
{
  unsigned thrdaddr;
  HANDLE hThread = reinterpret_cast<HANDLE>( _beginthreadex( NULL, 0,
    BusyLoopThProcEx, &dwTime, 0, &thrdaddr ) );
  if( hThread != NULL ){
    CloseHandle( hThread );
  }
}

 タスクマネージャなどの、CPU利用率を見れる状態で動作させてみてください。別途時間のかかる処理をしているらしいピーク状態を見せながら、なんの不都合もなく、プログラムが動いているのが分かると思います。今度は、時間のかかる処理を行っている最中にウィンドウを閉じてみてください。

 前編ではプログラムが終了せず、事実上のゾンビ状態になっていましたが、今度は時間のかかる処理の途中でプログラムが終了してしまいます。ゾンビにならないからいいのでは、という見方もありますが、途中で処理を放棄(実際には強制的にシャットダウンされる)となるため、ファイルへの書き込みなどがある場合は致命的な不具合につながる可能性があります。

 時間のかかる処理であっても、情報を渡したら後は勝手に自己完結的に処理を行うものであれば、このように待たずに次の作業ができるようにするのは有効な手段となります。しかし、最初の設計から別に動作するという前提を盛り込んでいない限りこのような実装にすることはできません。従って、前編同様何らかの形で処理終了を待たなければなりません。

メッセージを処理するスレッドと処理しないスレッド

 Windowsのスレッドには、メッセージを処理するスレッド(一般にUIスレッドなどと呼ばれる)と、メッセージを処理しないスレッド(一般にワーカースレッドなどと呼ばれる)の2種類があります。前者はUIスレッドと呼ばれるようにウィンドウを持ち、そのウィンドウが動くためにメッセージループを持つという特性を持ちます。それに対し、ワーカースレッドはユーザーインターフェースを一切もたないことで、メッセージループを回さなくてよいという特性を持ちます。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Windowsアプリケーションで「処理中」を表現する連載記事一覧
この記事の著者

とっちゃん(トッチャン)

Microsoft MVP for Development Tools Visual C++Windows Installer 系を中心にオンライン/オフラインで活動しています。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5352 2010/08/05 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング