1. 程式人生 > >使用C++11讓多執行緒開發變得簡單

使用C++11讓多執行緒開發變得簡單

#include <iostream>
#include <functional>
#include <map>
#include <vector>
#include <algorithm>
#include <cstring>
#include <thread>
using namespace std;
void func(){
    this_thread::sleep_for(chrono::seconds(3));
    cout << "do something" << endl;
}

int
main(){ thread t(func); //t.join();//函式func會運行於執行緒物件t中,join函式會阻塞執行緒,直到執行緒函式執行結束,如果執行緒函式有返回值,返回值被忽略 //t.detach();//將執行緒和執行緒物件分離,讓執行緒作為後臺執行緒去執行,當前執行緒也不會阻塞了 //需要注意的是detach()之後就無法再和執行緒發生聯絡了,比如detach之後就不能通過join來等待執行緒執行完,執行緒何時執行完我們也無法控制了 thread t1(move(t));//執行緒移動以後,t就不存在了,這個時候就不能呼叫t.join()函數了。 //t.join();-->error
cout << t1.get_id() << endl;//獲取當前執行緒id,22644 cout << "timeout" << endl; t1.join(); cout << t1.get_id() << endl;//獲取當前執行緒id,0,表示已經執行結束了. cout << std::thread::hardware_concurrency() << endl;//8核 return 0; }
#include <iostream>
#include <functional> #include <map> #include <vector> #include <algorithm> #include <cstring> #include <thread> #include <mutex> using namespace std; mutex glock; void func(){ glock.lock(); this_thread::sleep_for(chrono::seconds(3)); cout << "do something" << endl; glock.unlock();//加鎖封鎖操作 } void fun(){ lock_guard<mutex> lock(glock);//出作用域自動解鎖. cout << this_thread::get_id() << " works now" << endl; this_thread::sleep_for(chrono::seconds(3)); cout << "do something" << endl; } int main(){ thread t1(fun); thread t2(fun); thread t3(fun); t1.join(); t2.join(); t3.join(); return 0; }

一個執行緒池

#include <iostream>
#include <functional>
#include <map>
#include <vector>
#include <algorithm>
#include <cstring>
#include <thread>
#include <mutex>
using namespace std;
template <class T>
class ThreadPool{
    bool isFull() const {
        return m_queue.size() == m_maxSize;
    }
    bool isEmpty() const{
        return m_queue.empty();
    }
public:
    ThreadPool(int mSize) :m_maxSize(mSize){}
    void put(const T &value){
        unique_lock<mutex> locker(m_mutex);
        while (isFull){
            cout << "緩衝區滿了" << endl;
            m_notFull.wait(locker, [this](){return !isFull()});
        }
        m_queue.push_back(value);
        m_notEmpty.notify_one();
    }
    void get(const T&x){
        unique_lock<mutex> locker(m_mutex);
        while (isEmpty){
            cout << "緩衝區為空" << endl;
            m_notEmpty.wait(locker, [this](){return !is_empty()});
        }
        x = m_queue.pop_front();
    }
    bool Empty(){
        std::lock_guard<mutex>locker(m_mutex);
        return m_queue.empty();
    }
    bool Full(){
        std::lock_guard<mutex>locker(m_mutex);
        return m_queue.size() == m_maxSize;
    }
    size_t Size(){
        std::lock_guard<mutex>locker(m_mutex);
        return m_queue.size();
    }
    int count(){
        std::lock_guard<mutex>locker(m_mutex);
        return m_queue.size();
    }
private:
    condition_variable m_notEmpty;

    mutex m_mutex; //互斥量
    int m_maxSize; //執行緒池最大緩衝數目
    list<T> m_queue;//緩衝區,緩衝佇列

};

int main(){

    return 0;
}
#include <iostream>
#include <functional>
#include <map>
#include <vector>
#include <algorithm>
#include <cstring>
#include <thread>
#include <mutex>
#include <future>
#include <chrono>
using namespace std;


int main(){
    promise<int>pr;
    thread t([](promise<int>&p){
    p.set_value_at_thread_exit(100);
    }, ref(pr));
    t.join();
    //t.detach();必須選擇一個,否則程式會發生異常,不明白為什麼會發生異常.
    future<int>f = pr.get_future();
    auto i = f.get();
    cout << i << endl;

    packaged_task<int()> task([](){ return 7; });
    thread t2(ref(task));
    t2.join();
    future<int> fut = task.get_future();
    cout << fut.get() << endl;
    return 0;
}

C++11 提供了幾種非同步呼叫的方法,都能通過std::future來獲取非同步執行的結果。

  1. std::promise 可以用來線上程間提供資料傳遞。std::future = std::promise.get_future()。執行緒中可以對promise賦值std::promise.set_value。賦值之後std::future.get()就會返回其他執行緒中設定的值。

promise封裝了資料和future,將資料和future繫結起來,為獲取執行緒函式中的某一個值提供便利,線上程函式中為外面傳進來的promise賦值,線上程函式執行完成以後,,就可以通過promise的get_future方法獲取該值了

#include <iostream>  
#include <future>  
#include <chrono>  
std::promise<int> promis;
int main(int argc, const char * argv[]) {
    std::thread t([](std::promise<int>& promis){
        std::this_thread::sleep_for(std::chrono::seconds(10));
        promis.set_value_at_thread_exit(123);
    },ref(promis));
    t.detach();
    std::cout << "detach..." << std::endl;
    std::future<int> fuResult = promis.get_future();
    std::cout << fuResult.get() << std::endl;
    return 0;
}

2.std::packaged_task 可以包裹一個函式, 有點類似std::function,不同之處在於這個可以通過get_future返回std::future物件來獲取非同步執行的函式結果。
包裝了一個可呼叫物件的包裝類,如function, lambda expression, bind expression 和another function object,將函式和future繫結起來,以便非同步呼叫。

#include <iostream>  
#include <future>  
#include <chrono>  

int main(int argc, const char * argv[]) {
    int y;
    std::cin >> y;
    std::packaged_task<int(int)> m([](int x){
        std::this_thread::sleep_for(std::chrono::seconds(10));
        return x + 100;
    });
    std::future<int> fuResult = m.get_future();
    std::thread task(std::move(m),y); //給y加100,得到返回值.
    task.detach();
    std::cout << "detach..." << std::endl;
    std::cout << fuResult.get() << std::endl;
    return 0;
}
  1. std::async提供非同步執行的方法,std::future = std::async(…), 函式執行完成後可以通過std::future.get()獲取到執行函式的返回值

async()叫做執行緒非同步操作函式!!!

#include <iostream>  
#include <future>  
#include <chrono> 

int main(int argc, const char * argv[]) {

    std::future<int> fuResult = std::async([](){std::launch::async,
        std::this_thread::sleep_for(std::chrono::seconds(1));
        return 1;
    });
    std::cout << "detach..." << std::endl;
    std::cout << fuResult.get() << std::endl;
    return 0;
}
#include <iostream>  
#include <future>  
#include <chrono> 
using namespace std;
struct Base{
    void Fun()
    {
        cout << "it is fun" << endl;
    }
};
struct Derived:Base{
    using Base::Fun;//c++11新特性.
    void Fun(int a){
        cout << "it is fun in derived" << endl;
    }
};
int main() {
    Derived d;
    //d.Fun();//會產生編譯錯誤
    d.Fun();//這樣就不會出錯了.
    return 0;
}