关于并发(concurrency)的概述

/*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 }

猜你喜欢

转载自www.cnblogs.com/lhb666aboluo/p/12672145.html
今日推荐