ゲームプログラミングTips(2):ミューテックス

 

2012年3月11日……前回の講座より、なんと約4日も経過していた!
……「も」じゃねぇよ、凄く頑張ったよ!今後もこの調子で頑張るよ!……頑張れたらいいなぁ(´Д`)

 

1.ミューテックスとは?

 ggrks……と同じネタを何度も使うのもアレなので、早速説明。
 ミューテックスとは、「クリティカルセクションの拡大版」である(超適当)
 詳しいことはWikipediaに載っているので、そちらを参照するがよろし<また丸投げかよ!

 

2.ミューテックスのゲームプログラミングにおける活用事例

 前回紹介したクリティカルセクションは、(基本的に)1プログラム内での排他制御に用いるものである。
 それに対して、今回紹介するミューテックスは複数プログラム(というかマルチタスク環境)内での排他制御に用いるものである。
 「複数プログラム内で排他制御って何に使うの?」と思う貴方へ、実はあるのだ。いわゆる、アプリケーションの多重起動防止である。

 使い方を以下にて説明する。

 1.アプリケーションを起動する、起動したアプリケーションがミューテックスを作成する
 2.アプリケーションをもうひとつ起動する、起動したアプリケーションがミューテックスを作成しようと試みるが失敗する
 3.上で失敗したことにより「アプリケーションが既に起動している」ことが分かるため、2.で起動したアプリケーションは終了させる

 凄く単純な仕組みである。

 

3.具体例(ヘッダ解説)

 本項では、俺が作ったミューテックスクラスを掲載する。

/*************************************************
ファイル名:Mutex.h
作成者  :あびす
役割   :ミューテックス
*************************************************/
/**
*	@file	Mutex.h
*	@brief	相互排他を行うミューテックスクラスです。
* アプリケーションの二重起動防止に使用します。 */ #ifndef DX9A_MISC_MUTEX_H #define DX9A_MISC_MUTEX_H namespace nsDX9A{ namespace nsMisc{ namespace nsMutex{ //ミューテックス /** * @brief 相互排他を行うミューテックスクラスです。
* アプリケーションの二重起動防止に使用します。 */ class CMutex{ public: /** * @brief デフォルトコンストラクタです。 */ CMutex(); //デフォルトコンストラクタ /** * @brief デストラクタです。 */ ~CMutex(); //デストラクタ /** * @brief ミューテックス名をチェックし、既存かを取得します。 * @param MutexName [in]ミューテックス名を指定します。
* アプリケーション名等を指定してください。 * @return 既存でない(≒二重起動していない)場合はtrue、既存の(≒二重起動している)場合はfalseを返します。 */ bool Check(const string& MutexName); //ミューテックス名をチェック private: HANDLE m_Mutex; //ミューテックスオブジェクト CMutex(const CMutex&); //コピーコンストラクタ(禁止) CMutex& operator =(const CMutex&); //代入演算子(禁止) }; } } } #endif

 ヘッダに対する解説では本クラスの使用方法を説明する。使用方法は簡単である、

 1.インスタンスを生成する
 2.Checkメソッドを呼び出す
 3.戻り値がtrueの場合は二重起動しておらず、falseの場合は二重起動している
 4.falseの場合はアプリケーションを終了させる

具体例

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
	//多重起動をチェック
	CMutex Mutex;
	if(!Mutex.Check("てすとあぷり")){
		MessageBox(NULL, "多重起動は禁止されています!", "エラー!", MB_OK | MB_ICONWARNING);
		return(0);
	}
}

 ……これだけである(´Д`)
 余談だが、ゲームアプリケーションは必ず多重起動防止を施しておくべきである。
 ゲーム以外のアプリケーションは(ファイルの二重オープンさえなければ)多重起動しても問題はないが、
 ほとんどのゲームはセーブデータが局所的に存在する筈である(恐らくはひとつないしはセーブフォルダ内)
 そういった場合に多重起動防止を施しておかないと、ファイルの書き込みと読み込みが同時に起こる可能性がある。

 これはゲームアプリケーション特有のことであり、つまりゲームプログラミングTipsという本懐は守られている筈だ。
 どやぁ( ・´ー・`)

 

4.具体例(ソース解説)

 次はソース解説である。

#include "stdafx.h"
#include "Mutex.h"

namespace nsDX9A{
namespace nsMisc{
namespace nsMutex{

//デフォルトコンストラクタ
CMutex::CMutex(){
	m_Mutex = NULL;
}
//デストラクタ
CMutex::~CMutex(){
	if(m_Mutex){
		ReleaseMutex(m_Mutex);
		CloseHandle(m_Mutex);
	}
}

//ミューテックス名をチェック
bool CMutex::Check(const string& MutexName){
	m_Mutex = CreateMutex(NULL, TRUE, MutexName.c_str());
	return(GetLastError()!=ERROR_ALREADY_EXISTS);
}

}
}
}

 特に語るべきところはない、見たまんまである。
 作成を試みてエラーチェックの結果を返すだけ、細かい説明は省くのでググるがよろし。

 

 

 

……以上で本項は終了である、お疲れ様でした(´Д`)
今回は適当に書いてみたが、それでも三十分ぐらい掛かってしまった(;´Д`)
もうちょっと高速化して、ハナクソほじりつつ五分ぐらいで書いてうpしていきたいものである。
前回と今回、説明順序を逆にした方が良かったかなぁ? まあ、深いことは考えず今後も続けていく所存也。

 

前へ                                        戻る                                        次へ