goo blog サービス終了のお知らせ 

ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

Javaにおける、他プロセスとの共有メモリを考える

2007-08-22 14:56:46 | Weblog

 VC++であれば、他プロセスとの共有メモリというのが実現できる。
 これによって、

aaa.exe -start

 でプログラムをスタートさせ、

 aaa.exe -stop

 でプログラムをストップさせられる。

また、aaa.exeがすでに立ち上がっているとき、「このプログラムは2重起動できません」と、2重起動を防止することも可能になる。

 これを、Javaでやるには・・??

※念のため。javaでstaticで行うメモリ共有は、あくまでも、クラス内、同一プロセス内のメモリ共有の話であって、他プロセスとのメモリ共有ではない。




■VC++では、ミューテックスを使う。

 Javaの前に、VC++では、どうやるか?というと、ミューテックスを使う。

 ここのサイト

共有メモリを使用する
http://www.alpha-net.ne.jp/users2/uk413/vc/VCT_FileMapping.html


にやり方が分かりやすく書いてありますね。

 そのサイトのプログラムを引用して、上記
    aaa.exe -startでスタート、
    aaa.exe -stopで終了
 させるには、こうなるのかな?

#include "stdafx.h"

#include <afxmt.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 唯一のアプリケーション オブジェクトです。

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// MFC を初期化して、エラーの場合は結果を印刷します。
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: 必要に応じてエラー コードを変更してください。
		_tprintf(_T("致命的なエラー : MFC の初期化ができませんでした。¥n"));
		nRetCode = 1;
	}
	else
	{
		if ( argc	<=	1 )
		{
			errmsg();
		}
		else
		{
			if ( strcmp(argv[1],"-start")	==	0 )
			{
				zikko();
			}
			else if  ( strcmp(argv[1],"-stop")	==	0 )
			{
				syuryo();
			}
			else
			{
				errmsg();
			}
		}
	}

	return nRetCode;
}

/*======================================*/
/*	エラー表示		    */
/*======================================*/
int	errmsg()
{
	printf("書式¥r¥n");
	printf("開始するとき aaa -start¥r¥n");
	printf("終了するとき aaa -stop¥r¥n");
	return	0;
}

/*======================================*/
/*	終了処理			   */
/*======================================*/
int	syuryo()
{
	HANDLE m_hMapping;     // メモリマップドファイルのハンドル
	char *m_pMappingView;  // ファイルのビューへのポインタ
	CMutex *m_pMutex;      // ミューテックスオブジェクト

	// メモリマップドファイルの生成
	m_hMapping = ::CreateFileMapping(
			(HANDLE)0xffffffff,     // 共有メモリの場合は0xffffffffを指定
			NULL,                   // セキュリティ属性。NULLでよい
			PAGE_READWRITE,         // プロテクト属性を読み書き可能に指定
			0,                      // ファイルサイズの上位32ビット
			1024,                   // ファイルサイズの下位32ビット
			"SukinaNamae" );	// メモリマップドファイルの名前

	// プロセス内のアドレス空間にファイルのビューをマップ
	m_pMappingView = (char *)::MapViewOfFile(m_hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 1024);

	// ミューテックスオブジェクトの生成
	m_pMutex = new CMutex(FALSE, "UKFileMappingTest_Mutex");

	// ★共有メモリへ書き込む。このときミューテックスオブジェクトを
	// 使用して同期処理をおこなう
	m_pMutex->Lock(INFINITE);
	m_pMappingView[0]	=	1;
	m_pMutex->Unlock();

	return	0;
}

/*======================================*/
/*	実行(開始)		    */
/*======================================*/
int	zikko()
{
	//	共有メモリ用
	HANDLE m_hMapping;     // メモリマップドファイルのハンドル
	char *m_pMappingView;  // ファイルのビューへのポインタ
	CMutex *m_pMutex;      // ミューテックスオブジェクト
	char	end_flg;

	printf("★★★  開始  ★★★");
	// メモリマップドファイルの生成
	m_hMapping = ::CreateFileMapping(
			(HANDLE)0xffffffff,     // 共有メモリの場合は0xffffffffを指定
			NULL,                   // セキュリティ属性。NULLでよい
			PAGE_READWRITE,         // プロテクト属性を読み書き可能に指定
			0,                      // ファイルサイズの上位32ビット
			1024,                   // ファイルサイズの下位32ビット
			"SukinaNamae" );	// メモリマップドファイルの名前

	// プロセス内のアドレス空間にファイルのビューをマップ
	m_pMappingView = (char *)::MapViewOfFile(m_hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 1024);

	// ミューテックスオブジェクトの生成
	m_pMutex = new CMutex(FALSE, "UKFileMappingTest_Mutex");

	// ★共有メモリへ書き込む。このときミューテックスオブジェクトを
	// 使用して同期処理をおこなう
	m_pMutex->Lock(INFINITE);
	end_flg				=	0;
	m_pMappingView[0]	=	end_flg;
	m_pMutex->Unlock();

	/*==============================================*/
	/*					  */
	/*	ここに、やりたい処理をかく		  */
	/*					  */
	/*==============================================*/

	//	共有メモリが0の間ループ
	while(end_flg	==	0)
	{
		/*==============================================*/
		/*					  */
		/*	ここに、やりたい処理をかく		  */
		/*					  */
		/*==============================================*/
		Sleep(1000);	//	スリープさせてみました
				//	別にいらないですけど

		// ★共有メモリの内容を取得。このときミューテックスオブジェクトを
		// 使用して同期処理をおこなう
		m_pMutex->Lock(INFINITE);
		end_flg = m_pMappingView[0];
		m_pMutex->Unlock();
	}

	/*==============================================*/
	/*					  */
	/*	ここに、やりたい処理をかく		  */
	/*					  */
	/*==============================================*/

	// ★ファイルのビューをアンマップし、マップのハンドルをクローズ
	BOOL b = ::UnmapViewOfFile(m_pMappingView);
	::CloseHandle(m_hMapping);

	// ★ミューテックスオブジェクトの破棄
	delete m_pMutex;

	printf("★★★  終了  ★★★");
	return	0;
}


(上記 < > ¥は、本当は半角)

対応が分かりやすくなるように、引用元のコメントはそのままにしてあります。

SukinaNamaeのところは、ミューテックスに、好きな名前をつけてください
ここの名前が同じものが共有できます。

最近は、ここによると、CreateFileMapping() でなく、VirtualAllocEx()でもできるみたいだけど。。




■で、Javaでは・・・

 じゃ、Javaで、他プロセス間の共有メモリを使うには?・・・

 そっだ!

 VC++で、上記のプログラムをちょこっとかえて、
   共有メモリを読み込むプログラムと
   共有メモリに書き込むプログラムを
 作成して、

 それを、JNIを使って呼び出せばよい・・・


 だから、表題は、「考える」って書いただけで、

 「Java”だけ”でできる」ってかいてないっすよお・・・

 ぎゃあー。。おこらないでくださいよおお・・

 旗色が悪そうなので、ここらへんで(^^;)


この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 開発の初めから順番に書いて... | トップ | ログインしたら、最小化の状... »
最新の画像もっと見る

Weblog」カテゴリの最新記事