C++マルチスレッド-第2編-Mutex(反発量)


//Boost#include#define BOOST_THREAD_VERSION 4//最新バージョンを使用し、1,2,3を含むが、以前のプログラムと互換性を持つためだけである.
Threadライブラリは強力な拡張機能を豊富にしていますが、Threadでは見られません.
//C++11
#include
using namspace std; 
Mutex(反発量)
1.Mutexクラス
基本的な役割:反発は変数を占有し、しばらくの間1つのスレッドだけがアクセスできます.
すなわち、クラスは、ある物へのアクセスを制限することができ、先に許可を得てこそ、ある物にアクセスすることができ、そうでなければ、一般的にブロック待機とすることができる.
 
反発量*6
mull_mutex
ロック機能のない反発量は、空のオブジェクトモードで使用されます.
mutex
排他的反発量、最も簡単ですが最もよく使われます
timed_mutex
排他的反発量は、一定期間ロックしようとし、タイムアウトするとfalseを返します.
recursive_mutex
再帰的な反発量、複数回ロックすることができて、相応するのも複数回ロックを解除します
Recursive_timed_mutex
再帰的反発量は,同様に一定時間増加してロックしようとし,タイムアウトするとfalseを返す.
Shared_mutex
マルチ読者、シングルライターの共有反発量(読み書きロック)
 
一般メンバー関数:
Class Mutex
{
Public:
Void lock();//ロックしないとブロックされます
Void unlock();//ロック解除
Bool try_lock();//ロックしてみますが、ブロックされません
Bool try_lock_for(const duration &rel_time); //timed_特有で、しばらくブロックした後にロックを試みます
Bool try_lock_until(const time_point &t);// timed_特有で、しばらくブロックした後にロックを試みます
 
others...
};
 
Code:
mutex mutex_thread_1;
try
{
	mutex_thread_1.lock();
	cout << "Do Something" << endl;

	mutex_thread_1.unlock();

}
catch (std::exception e)
{
	//cout <<  << endl;;
	mutex_thread_1.unlock();
}


timed_mutex t_mutex_1;
auto flag = t_mutex_1.try_lock_for(boost::chrono::milliseconds(100));
if (flag)
{
	cout << "    " << endl;
	t_mutex_1.unlock();
}
else
{
	cout << "    ,      " << endl;
}

 
2.Lock_guard()--Muteの優秀な補助
役割:このような補助ロック反発量は、構造時にロックされ、分析時にロックされ、ロックを忘れないようにします.つまり、その役割ドメイン内で要求される変数をロックし続けます.
スマートポインタに似ていますか?
追加拡張:with_lock_guard()はlock_を借りてguard()は関数の中であるロックリソースを反発して使用し、(関数をカプセル化するために?)
 
mutex mu;
lock_guard g(mu);//          /  
cout << "Do  something" << endl;

timed_mutex t_mu;
if (mu.try_lock_for(boost::chrono::microseconds(100)))
{
	lock_guard g(t_mu,adopt_lock);//      
	cout << "Do something" << endl;
}


#include 
#bind()   
//with_lock_guard
mutex fmu;
string name = "ZGJ";
int rul = with_lock_guard(fmu, bind(Alloa,argv1,argv2...));//       , Boost     ,Alloa   ,argv    
cout << rul << endl;

With_lock_guard(lockable& m, Function && fun, Args &&...args)    
{
	Lock_guard g(m);
	Return func(argc...)
}


 

3. unique_lock()-- lock_guard()

, 。 : ---

 unique_lock(Lockable & mu) ;//

 unique_lock(Lockable & mu,boost::adopt_lock_t);// ,

 unique_lock(Lockable & mu,boost::defer_lock_t);//

 unique_lock(Lockable & mu,boost::try_to_lock_t);//

 unique_lock(Lockable & mu,const time_point &t);//


make_unique_lock(Lockable &mu,option);

// unique_lock(), ,

templat

unique_lock my_make_unique_lock(lockable& mu, T_ my_x)

{
return unique_lock(mux,my_x);

}


Code:

#include

mutex m_un_lock;
{	//          , make_unique_lock    。
	auto g = make_unique_lock(m_un_lock);//         
	assert(g.owns_lock());//   --     
	cout << "Do something" << endl;
}

{
	auto g = make_unique_lock(m_un_lock, defer_lock);//       
	assert(!g);//    --     

	assert(g.try_lock());//    
	assert(g);//   --     
	cout << "Do something" << endl;
}

timed_mutex t_mu_un;
{
	auto g = unique_lock(t_mu_un, boost::chrono::milliseconds(100)); //  100MS    
	if (g)
	{
		cout << "Lock timed mutex" << endl;
	}
}
auto g = make_unique_locks(t_mu_un, m_un_lock);//         
assert(std::tuple_size::value == 2);//      2 


4.Lock /Lock /lock

4.1Lock

。 lock , lock_guard()/unique_lock() 。

Lock_guard   unique_lock <LockAble>( lock/unlock/try_lock

, 。

 

Lockable Lockable

Basic_lockable_adapter 

lock unlock

 

Lockable_adapter

try_lock

 

Timed_lockable_adapter

try_lock_for/try_lock_until

 

Code:

#include
#include
#include//   
#include //Lockable    
#include
using namespace std;
using namespace boost;

class account : public lockable_adapter
{
private:
	atomic m_money_{ 0 }; //    
public:
	account(){}
	~account(){}
	int sum()const
	{
		return m_money_;
	}
	void withdraw(int x)
	{
		m_money_ -= x;
	}
	void deposit(int x)//  
	{
		m_money_ += x;
	}
	void show()
	{
		cout << m_money_ << endl;
	}
};

int main()
{

	account a;
	{
		auto g = make_unique_lock(a);
		a.deposit(100);
		a.show();
		a.withdraw(20);
		a.show();
		assert(a.sum() == 80);
	}

{
	auto b = make_unique_lock(a, try_to_lock);
	if (b)
	{
		a.withdraw(a.sum());
		assert(a.sum() == 0);
		a.show();
	}
}
return 0;

}


4.2.Lock

Lockable , 。

 

4.3.Lock

Lock() / try_lock() mutex make_unique_locks()  Mutex, 。 ,

unique_lock adopt_lock defer_lock , .

 

Code:

 

mutex m1, m2;
{
	auto g1 = make_unique_lock(m1, adopt_lock);
	auto g2 = make_unique_lock(m2, adopt_lock);
	lock(m1, m2);
}//unique_lock    

{
	auto g1 = make_unique_lock(m1, defer_lock);
	auto g2 = make_unique_lock(m2, defer_lock);
	try_lock(g1, g2);
} //unique_lock    

5. :Shared_mutex.

----


Code:

#include
#include
#include
#include
#include
using namespace std;
using namespace boost;

class rw_data
{
private:
	int m_x;
	shared_mutex rw_mu;
public:
	rw_data() :m_x(0){}
	void write()
	{
		unique_lock g(rw_mu);
		++m_x;
	}
	void read(int &x)
	{
		shared_lock g(rw_mu);
		x = m_x;
	}

};
mutex xzz;
void writer(rw_data &d)
{
	for (int i = 0; i < 2; ++i)
	{
		this_thread::sleep_for(chrono::microseconds(3000));
		d.write();
	}
}
void reader(rw_data &d)
{
	int x;
	for (int i = 0; i < 10; i++)
	{
		this_thread::sleep_for(chrono::microseconds(5000));
		d.read(x);
		xzz.lock();
		cout << this_thread::get_id() << "reader:" << x << endl;
		xzz.unlock();
	}
}

int main()
{
	//     
	rw_data d;
	thread_group pool;
	pool.create_thread(bind(writer, boost::ref(d)));
	pool.create_thread(bind(writer, boost::ref(d)));

	pool.create_thread(bind(reader, boost::ref(d)));
	pool.create_thread(bind(reader, boost::ref(d)));
	pool.create_thread(bind(reader, boost::ref(d)));
	pool.create_thread(bind(reader, boost::ref(d)));

	pool.join_all();
	std::system("pause");
	return 0;
}