ページ 11

排他処理のロジックについてアイディアを相談させてください

Posted: 2012年3月22日(木) 11:47
by ヨシカワ
複数スレッドによる検索処理を行っています。
以下のSearcherクラスのインスタンスを複数スレッドで共有し、Search()、RenewDB()が非同期に呼ばれます。
Search()同士が同時に呼ばれるのは文字列チェックのみなので排他処理は必要ないのですが、RenewDB()とSearch()が同時に呼ばれたときに
排他処理が必要になります。 (m_aDBの操作中に検索を行うと最悪アボートする可能性があるので)

この場合の排他処理の実装方法がいまいちわからないのですが、アイディアがあれば御教授お願いできないでしょうか?
各メソッドの開始、終了でクリティカルセクションのLock、Unlockを行えば一番簡単ですが、Search()の同時呼び出しもロックがかかってしまいダメです。

コード:

 
class Searcher {

	bool Search(CString str) {
		
		//Search()同士は非同期に呼ばれても良い
		//Search()とRenewDB()間だけ排他処理を行う
		
		for(int i = 0; i < m_aDb.size()) {
			if(str == m_aDb[i]) {
				return true;
			}
		}
		return false;
	}
	
	void RenewDB() {
		//m_aDBの更新を行う
	}

private:
	vector<CString> m_aDB;
	
}

Re: 排他処理のロジックについてアイディアを相談させてください

Posted: 2012年3月22日(木) 12:04
by たいちう@出先
Searcherのメンバ変数で、Searchを実行中のスレッド数等を管理してはどうでしょうか。
ReNewDBはSearchが実行されていたら待機フラグを立てて待機します。
詳しく漏れなく説明するのは面倒なので、参考図書を紹介します。

『増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編』


Javaなので実装方法は違いますが、
アイディアについてはこの本が非常に役に立ちます。
私はこの本のサンプルをC++で実装することで、
スレッドの理解が深まりました。

Re: 排他処理のロジックについてアイディアを相談させてください

Posted: 2012年3月22日(木) 12:19
by beatle
やりたいのはRead Write Lockではないでしょうか。
Java Tips: かしこいロック

C++で実装するにはC++時代のread-write lockが役立ちそうです。

Re: 排他処理のロジックについてアイディアを相談させてください

Posted: 2012年3月22日(木) 12:27
by YuO
readers/writer lockパターンが使えると思います。

CStringという名前からWindows系を想定しますが,Windows Vista以降であればSlim Reader/Writer LocksというAPI群があります。
Slim Reader/Writer (SRW) Locks (Windows)

Re: 排他処理のロジックについてアイディアを相談させてください

Posted: 2012年3月22日(木) 12:51
by ヨシカワ
早々に返信ありがとうございます。
Read Write Lockを知りませんでしたが、まさしくこれが当てはまります。
環境がC++なので教えていただいたURLを参考実装したいと思います。