複数のmutexが必要な状況を考えてみた。
// 排他的にアクセスするリソース
class exclusive_resource
{
public :
std::vector<int> v ;
private :
std::mutex m ;
public :
void lock() { m.lock() ; }
void try_lock() { m.try_lock() ; }
void unlock() { m.unlock() ; }
} ;
exclusive_resource res1, res2 ;
void thread1()
{// res1のみを操作
std::lock_guard< exclusive_resource > guard( res1 ) ;
res1.v.push_back(0) ;
}
void thread2()
{// res2のみを操作
std::lock_guard< exclusive_resource > guard( res2 ) ;
res2.v.push_back(0) ;
}
void thread3()
{// res1, res2両方を操作
std::lock( res1, res2 ) ; // デッドロックを回避するためstd::lockを使用すること
// res1, res2両方を操作、実際には途中のreturnや例外に気をつけること
res1.unlock() ; res2.unlock() ;
}
void thread4()
{// thread3と同じく、res1, res2の両方を操作、thread3とは異なる処理
std::lock( res1, res2 ) ; // デッドロックを回避するためstd::lockを使用すること
// res1, res2両方を操作、実際には途中のreturnや例外に気をつけること
res1.unlock() ; res2.unlock() ;
}
今、異なるスレッド間で操作したいオブジェクトが複数あるとする。しかし、常に全オブジェクトを操作する必要はないものとする。とすれば、この複数のオブジェクトを、単一のmutexで排他的にアクセスするのは、非効率的である。したがって、アクセスしたい単位ごとに、別々のmutexを用意するのは当然である。
しかしまた、ある状況では、複数の単位に、同時にアクセスしたい場合もあるとする。この場合、複数のmutexをlockしなければならない。しかし、普通に一つづつlockしたのでは、デッドロックに陥る可能性がある。このため、デッドロックを避けるように気をつけつつロックしなければならない。
std::lockは、lock(), try_lock(), unlock()を組み合わせた一連の呼び出しにより、デッドロックに陥らない方法で、すべてのLockable要求を満たす型のオブジェクトをロックしてくれる。
まとめとしては、複数のmutexを同時にlockする際には、デッドロックを避けるために、std::lockを使うべきである。
203 comments:
«Oldest ‹Older 201 – 203 of 203very nice online tutoring sites
very nice nettutor
Very Niceaccounting classes online
Post a Comment