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