SHOEISHA iD

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

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

japan.internet.com翻訳記事

C++でのスレッドクラスの作成

プラットフォームに依存しないスレッド処理をC++で実現する方法

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

ダウンロード サンプルソース (13.2 KB)

ここでは次のような特徴を持ったスレッドクラスを考えてみましょう。イベントドリブンとインターバルベースの両方の非同期スレッド処理に対応していること、均一型と細分型の両方のスレッド処理に対応していること、先着順方式のスタックキューを備えていること、移植可能であること、そして簡単に実装できることです。

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

はじめに

 先日、私の兄弟から、オブジェクト指向のスレッド処理を楽にするC++クラスを簡単に作成する方法はないだろうかという相談を受けました。私はこれまで、さまざまなマルチスレッドライブラリを作成した経験がありますが、いずれもC言語によるものでした。低レベルのプログラミングには私はいつもC言語を使用し、C++はもっぱらGUI開発に使用しています。CodeGuruにはオブジェクト指向でスレッド処理を行うクラスの優れた例が色々と掲載されていますが、彼の要望をすべて満たし、かつ私の好奇心をも満たすクラスは見当たりませんでした。彼が求めていたのは、次のような特徴を備えたスレッドクラスでした。

  • イベントドリブンとインターバル(間隔)ベースの両方の非同期スレッド処理に対応している
  • 均一型と細分型の両方のスレッド処理に対応している
  • 複数タスクを格納して処理できる、先着順(FCFS:First Come First Serve)方式のスタックキューを備えている
  • 移植可能である
  • 簡単に実装できる

 そこで私は、CThreadという新しいクラスと、併せて使用するサポートクラスをいくつか作成しました。サポートクラスとして用意したのは、CMutexClassクラス、CEventClassクラス、CTaskクラスです。CMutexClassとCEventClassは、リソース管理を行うためのクラスです。CTaskは、均一型の非同期スレッド処理を行うクラスを作成するための基本クラスです。

スレッド処理とは何か

 プロセスは必ず1つ以上のスレッドを制御しており、各プロセスは一度に少なくとも1つのタスクを実行できます。複数のスレッドを制御しているプロセスのことを、マルチスレッドプロセスといいます。マルチスレッドプロセスでは、同じプロセスの環境内から複数のタスクを非同期で実行できます。

リソース管理――スレッドの同期

 同じマルチスレッドプロセスに属する各スレッドは、同じリソースを共有します。したがって、データ整合性を確保するために、OSレベルの制御機構が必要です。データ整合性が損なわれるのは、たとえばあるスレッドが変数を変更しようとしているときに別のスレッドがその変数を読み込もうとした場合や、2つのスレッドが同じ変数を同時に変更しようとした場合です。OSには、こうした状況を防ぐためのしくみが用意されています。その名は、相互排他オブジェクト(Mutual Exclusion Object)、略して「ミューテックス(mutex)」です。マルチスレッドアプリケーションでは、プログラムで配置したミューテックスによって、複数のスレッドが単一のリソースに同時にアクセスする事態を防ぎます。

 スレッドは、リソースにアクセスする必要が生じると、まずミューテックスを取得します。いずれかのスレッドがミューテックスを取得しているときには、同じミューテックスを取得しようとした他のスレッドはブロックされ、CPU使用率の低い待ち状態に置かれます。データアクセスが完了したスレッドは、対応するミューテックスを解放します。これを受けて、他のスレッドがそのミューテックスを取得できるようになり、対応するデータにアクセスできます。

 ミューテックスの実装に問題があると、いわゆる「デッドロック」が発生することがあります。デッドロックとは、1つまたは複数のスレッドが、同じリソースへのアクセスを求めて競合している状態です。デッドロックは、スレッドがミューテックスを2回取得しようとした場合にも発生することがあります。

デッドロックの例
スレッドAスレッドB
ミューテックス(1)を取得し、データ項目1を変更ミューテックス(2)を取得し、データ項目2を変更
データ項目2を参照するためにミューテックス(2)が必要データ項目1を参照するためにミューテックス(1)が必要

 上の例ではデッドロックが発生します。スレッドAは、スレッドBが保持するミューテックス(2)を取得しようとしてブロック状態になり、スレッドBは、スレッドAが保持するミューテックス(1)を取得しようとしてブロック状態になるからです。

 UNIXの条件変数も、ミューテックスと同様、スレッドを同期させるためのしくみの1つです。条件変数では、スレッド同士を連係させることが可能です。あるスレッドから別のスレッドに対し、変更が発生したことを通知できます。Windowsでは、その機能はイベントで実現されます。

オペレーティングシステムコール

 次の表は、CMutexClass、CEventClass、CTask、CThreadの各クラスでスレッド処理の実装に使用した関数の一覧です。

関数OS説明使用したクラス
CreateThreadWindowsWindowsでスレッドを作成するCThread
pthread_createUNIX - POSIXスレッドUNIXでスレッドを作成するCThread
pthread_joinUNIX - POSIXスレッドUNIXでスレッドの終了を待機するCThread
pthread_attr_initUNIX - POSIXスレッドスレッド属性構造体をデフォルト値に設定するCThread
pthread_attr_setstacksizeUNIX - POSIXスレッドスレッド属性構造体のスタックサイズ値を設定するCThread
WaitForSingleObjectWindowsオブジェクトがシグナル状態になるのを待機するCThread、CMutexClass、CEventClass
CreateMutexWindows名前付きまたは匿名のミューテックスを作成するCMutexClass
CloseHandleWindowsWindowsハンドルへのリソース割り当てを解放するCMutexClass、CEventClass、CThread
ReleaseMutexWindowsWaitForSingleObjectでロックされた取得済みのミューテックスを解放するCMutexClass、CEventClass
pthread_mutexattr_initUNIX - POSIXスレッドミューテックス属性構造体を初期化するCMutexClass、CEventClass
pthread_mutex_initUNIX - POSIXスレッド指定の属性構造体でミューテックスを初期化するCMutexClass、CEventClass
pthread_mutex_lockUNIX - POSIXスレッドミューテックスをロックするCMutexClass、CEventClass
pthread_mutex_unlockUNIX - POSIXスレッドpthread_mutex_lockでロックしたミューテックスのロックを解除するCMutexClass、CEventClass
pthread_mutex_destroyUNIX - POSIXスレッドミューテックスに割り当てられたリソースを解放するCMutexClass、CEventClass
CreateEventWindowsWindowsのイベントオブジェクトを作成するCEventClass
SetEventWindowsWindowsのイベントオブジェクトをシグナル状態に設定するCEventClass
pthread_cond_signalUNIX - POSIXスレッドpthread_cond_waitでブロックされたスレッドのブロックを解除するCEventClass
pthread_cond_waitUNIX - POSIXスレッド条件変数に基づいてブロックするCEventClass
pthread_cond_initUNIX - POSIXスレッド条件変数を初期化するCEventClass

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

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

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

メールバックナンバー

次のページ
CMutexClassクラス

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

  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

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

Walter Capers(Walter Capers)

Compuware社のソフトウェアアーキテクトで、ソフトウェアセキュリティを専門としている。言語はC/C++、FORTRAN、COBOL、Java。ライブラリはOpenGL、MFC、WIN32。経験のあるプラットフォームはAIX、HP-UX、SunOS、Open VMS、OSF、AS400、AIX、...

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

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

この記事をシェア

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

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング