6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C++/CLIとC++混在でstd::mutex使えないのでその代わりを実装

Last updated at Posted at 2018-12-05

#C++/CLIとC++混在でstd::mutex使えない
C++/CLIが呼び出しているC++の関数内で排他制御したいがstd::mutex使うと
VS2017ではビルド時に「 is not supported when compiling with /clr or /clr:pure」というエラーになる。

C++/CLIだけならば代わりにmsclr\lock.hが使えるがC++では使えない。
ついでに、調べるとWLRとかいうのでも使えそうなものが試すとこれもエラーに。

C++/CLIが呼び出しているC++内で排他制御するにはwinAPIを使うしかないっぽい。
以下を使う。

#include<windows.h>

//初期化 コンストラクタなどで
HANDLE hMutex = CreateMutex(NULL,FALSE,NULL);

//ロック取得
WaitForSingleObject(hMutex, INFINITE);
//なんか排他的に実行したい処理

//ロック解放
ReleaseMutex(hMutex);

//終了 デストラクタなどで
CloseHandle(hMutex);

しかし、これを素直に使うとロック解放忘れ、クローズし忘れでバグ作りそうなので、std::lock_guardのようにロック取得したブロック(lock_guardのインスタンスのスコープ)を抜けると勝手にロック解放されるようにしたい。

ネット探すと無駄に高機能な実装みたいなのが見つかった気がするけど、そんな大した機能はいらないのでMutex限定で超簡単な実装を作ってみた。

#std::mutex、std::lock_guardの代わりの実装

ヘッダーオンリーです。
どうぞご自由に改変、ご使用ください。
ソースはhidetaka0/VCppMutexにも上げています。

Mutex.h
#pragma once
#include <windows.h>

class Mutex
{
private:
	HANDLE g_hMutex;

public:
	Mutex()
	{
		//Mutex生成
		g_hMutex = CreateMutex(NULL, FALSE, NULL);
	}

	~Mutex()
	{
		//クローズ
		CloseHandle(g_hMutex);
	}

	//ロック
	void Lock()
	{
		WaitForSingleObject(g_hMutex, INFINITE);
	}
	//アンロック
	void Unlock()
	{
		ReleaseMutex(g_hMutex);
	}
};

class MutexLockGuard
{
private:
	Mutex * g_Mutex;

public:
	MutexLockGuard(Mutex * mutex)
	{
		g_Mutex = mutex;
		g_Mutex->Lock();//ロック
	}

	~MutexLockGuard()
	{
		g_Mutex->Unlock();//アンロック
	}
};

#使い方

①Mutexクラスのインスタンス作成
②ロックしたいブロックでMutexLockGuardのコンストラクタに①のインスタンスのアドレス与えてインスタンスを生成する。

MutexTest.h
#pragma once
#include "Mutex.h"

class MutexTest
{
public:
	MutexTest();
	~MutexTest();
public:
	//Mutexクラスのインスタンス
	Mutex MyMutex;
	//テスト用数
	void TestRun()
	{
		//ロック取得
		{
			MutexLockGuard lock(&MyMutex);//ブロックを抜けると勝手にアンロック

			//なんか排他的に実行したい処理
			//・・・

		}

	};
};


6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?