/*about mutex and unique_lock*/ mutex m; //controlling mutex int sh; //shared data void f() { unique_lock<mutex> lck{ m }; //acquire mutex sh += 7; //manipulate shared data } //release mutex implicitly ---------------------------------------------------------------------- /*about defer_lock*/ //acquire several locks simultaneously //defer_lock can avoid deadlocking void f() { //... unique_lock<mutex> lck1{ m1,defer_lock }; /*defer_lock:don't yet try to auqire the mutex*/ unique_lock<mutex> lck2{ m2,defer_lock }; unique_lock<mutex> lck3{ m3,defer_lock }; //... lock(lck1, lck2, lck3); //acquire all three locks //...manipulate shared data... } //implicityly release all mutexes ---------------------------------------------------------------------- /*about condition_variable*/ class Message { //object to be communicated //... }; queue<Message> mqueue; //the queue of messages condition_variable mcond; //the variable communicating events mutex mmutex; //the locking mechanism void consumer() { while (true) { unique_lock<mutex> lck{ mmutex }; //acquire mmutex while (mcond.wait(lck))/*do nothing*/; //release lck and wait //re-acquire lck upon wakeup auto m = mqueue.front(); //get the message mqueue.pop(); lck.unlock(); //release lck //...process m... } } void producer() { while (true) { Message m; //...fill the message... unique_lock<mutex> lck{ mmutex }; //protect operations mqueue.push(m); mcond.notify_one(); //notify } //release lock(at end of scope) } ----------------------------------------------------------------------- /*about future and promise*/ void f(promise<X>& px) //a task: place the result in px { //... try { X res; //...compute a value for res... px.set_value(res); } catch (...) { //oops:couldn't compute res //pass the exception to the future's thread px.set_exception(current_exception()); } } void g(future<X>& fx) //a task: get the result from fx { //... try { X v = fx.get(); //if necessary,wait for the value to get computed //...use v... } catch (...) { //oops: someone couldn't compute v //...handle error... } } -------------------------------------------------------------------- /*about packaged_task and thread*/ double accum(double* beg, double* end, double init) //compute the sum of[beg:end) starting with the initial value init { return accumulate(beg, end, init); } double comp2(vector<double>& v) { using Task_type = double(double*, double*, double); //type of task packaged_task<Task_type> pt0{ accum }; //package the task packaged_task<Task_type> pt1{ accum }; future<double> f0{ pt0.get_future() }; //get hold of pt0's future future<double> f1{ pt1.get_future() }; //get hold of pt1's future double* first = &v[0]; thread t1{ move(pt0),first,first + v.size() / 2,0 }; //start a thread for pt0 thread t2{ move(pt1),first + v.size() / 2,
first + v.size(),0 }; //start a thread for pt1 //... return f0.get() + f1.get(); //get the results } ---------------------------------------------------------------- /*about async()*/ double comp4(vector<double>& v) //spawn many tasks if v is large enough { if (v.size() < 10000) return accum(v.begin(), v.end(), 0.0); auto v0 = &v[0]; auto sz = v.size(); auto f0 = async(accum, v0, v0 + sz / 4, 0.0); //first quarter auto f1 = async(accum, v0 + sz / 4, v0 + sz / 2, 0.0); //second quarter auto f2 = async(accum, v0 + sz / 2, v0 + sz * 3 / 4, 0.0); //third quarter auto f3 = async(accum, v0 + sz * 3 / 4, v0 + sz, 0.0); //fourth quarter return f0.get() + f1.get() + f2.get() + f3.get(); //collect and combine the results }
关于并发(concurrency)的概述
猜你喜欢
转载自www.cnblogs.com/lhb666aboluo/p/12672145.html
今日推荐
周排行