C++11同時多発とマルチスレッドまとめ(三)--unique_lock置換lock_guardy


文書ディレクトリ


(一)スレッド概念、作成およびパラメータ伝達(二)排他的反発ロック–mutex,lock_guardyと他のmutex(3)unique_lock置換lock_guardy(四)単一例モード(Singleton)でのスレッドセキュリティ問題(五)window臨界領域(六)condition_variable条件変数(7)std::async非同期タスクとstd::future<>(8)packaged_task<>とpromise<>(九)原子操作atomic<>の概要
(1)unique_lockクラステンプレート
1.unique_lockは柔軟ですが、lockより効率的です.guardは少し低く、メモリを多く消費します.第2パラメータ転送std::adop_lock,とlock_guardと同様に使用する前にlock 3を先にしなければならない.第2パラメータ転送std::try_to_ロック、ロックを取ってから行い、詰まりが発生せず、使用前にロック4をすることはできません.第2パラメータ転送std::defer_lockは、使用前にlockすることができず、作成後に自分でロックをかけることができ、自分でlockとunlockの最後の分析も自動的にロックを解除することができる.release()mutex所有権を解放し、解放後手動ublock 6を必要とする.所有権を渡すにはstd::move()関数を使用し、スマートポインタunique_とptr 7.関数return std::unique_を使用することもできます.lockstd::mutexはローカルオブジェクトシステムに戻って移動構造関数を呼び出す
  • パラメータadop_lockの使い方はlock_と同じですguard
  • std::mutex m_mutex;
    m_mutex.lock()
    std::unique_lock<mutex> l1(m_mutex,std::adopt_lock);  // lock, lock_guard, 
    //...
    // 
    //...
    unique_lock.unlock() // 
    //...
    // ....
    //...
    unilock.lock(); // , , 
    				// unlock , 
    				// 
    
  • パラメータtry_to_lockは
  • を塞ぐことはありません
    	std::unique_lock<mutex> getlock(m_mutex,std::try_to_lock);  // 
    	if (getlock.owns_lock())
    	{
    		// ...
    	}
    	else
    	{
    		cout << " ~~~ ~~~~"<< endl;
    	}
    
  • パラメータdefer_ロックは自分で鍵をかける必要があります
  • 	std::unique_lock<mutex> unilock(m_mutex1, std::defer_lock);
    
    	unilock.lock(); // 
    
    	m_list.push_back(i);
    	cout << "write  " << i << endl;
    
    	unilock.unlock();
    
    	// ....
    
    	unilock.lock(); // , , 
    	//...
    	unilock.unlock();
    
  • releaseバインドを解放し、ポインタ
  • に戻る
  • コードセグメント
  • を参照
  • テストコード
  • #include 
    #include
    #include
    #include
    
    using namespace std;
    
    class CReadAndWrite
    {
    public:
    	CReadAndWrite() {};
    	void read();
    	void wirte();
    
    private:
    	list<int> m_list;
    	mutex m_mutex1;
    	mutex m_mutex2;
    };
    
    void CReadAndWrite::wirte()
    {
    	for (int i = 0; i < 100; i++)
    	{
    		//m_mutex1.lock();
    		//std::unique_lock l1(m_mutex1,std::adopt_lock);  // lock, lock_guard
    
    		std::unique_lock<mutex> unilock(m_mutex1, std::defer_lock);
    
    		unilock.lock();
    
    		m_list.push_back(i);
    		cout << "write  " << i << endl;
    
    		unilock.unlock();
    
    		// ....
    
    		unilock.lock(); // , , 
    
    		std::mutex* mut = unilock.release(); // , 
    		mut->unlock(); // , , 
    	}
    }
    
    void CReadAndWrite::read()
    {
    	for (int i = 0; i < 100; i++)
    	{
    		if (m_list.size())
    		{
    
    			std::unique_lock<mutex> unilock(m_mutex1, std::try_to_lock);  // lock
    
    			std::unique_lock<mutex> getlock(std::move(unilock));  // move
    
    			if (getlock.owns_lock())
    			{
    				int num = m_list.front();
    				cout << "  num = " << num << endl;
    				m_list.pop_front();
    			}
    			else
    			{
    				cout << " ~~~ ~~~~"<< endl;
    			}
    
    		}
    		else
    			cout << " ~~~~" << endl;
    	}
    }
    
    
    
    int main()
    {
    
    
    	CReadAndWrite obj;
    	thread mywrite(&CReadAndWrite::wirte, &obj);
    	thread myread(&CReadAndWrite::read, &obj);
    
    	mywrite.join();
    	myread.join();
    
    	std::cout << "Hello World!
    "
    ; }