1. 程式人生 > 實用技巧 >future 擴充套件 、原子操作 std::atomic

future 擴充套件 、原子操作 std::atomic

一、future 擴充套件

1、future 的其他成員函式

class MyClass
{
public:
    int MyThread(int param);   // 假定一個執行緒函式是有返回值的
};

int main()
{
    MyClass ele;
    std::future<int> result = std::async(&MyClass::MyThread, &ele, 5);

    std::future_status status = result.wait_for(std::chrono::seconds(2));
    
// 此時等待2秒。 返回示 result 繫結的執行緒執行了2秒之後,目前的狀態 if (status == std::future_status::timeout) { // 超時:表示執行緒還是沒有執行完,即執行緒執行的時間超過2秒 // 最終在主執行緒return 0 之前,會等待執行緒執行完 } else if (status == std::future_status::ready) { // 表示執行緒成功返回 // 此時可以得到執行緒執行後的結果 } else if (status == std::future_status::deferred) {
// 表示執行緒會被延遲建立,如果沒有呼叫future.get() 函式,執行緒不會被建立 // 與第一個引數 std::async() 第一個引數為 std::launch::deferred 的情況相同, 與下句意思相同 // std::future<int> result = std::async(std::launch::deferred, &MyClass::MyThread, &ele, 5); result.get(); // 直到這句話才會執行 } system("pause"); return
0; }

2、shared_future

// future.get() 函式是一個移動語義,所以只能呼叫一次 future的get()函式,否則會編譯報錯
// 如果一個執行緒中的結果,要被其他多個執行緒使用,則需要用std::shared_future
// std::shared_future 的 get() 函式是一個複製語義

std::future<int> result = std::async(&MyClass::MyThread, &ele, 5);
std::shared_future<int> result_s(std::move(result)); 
// std::shared_future<int> result_s(result.share()); 
// 這兩種方式都可以,都是移動語義
// 執行完畢後,result_s有值,result為空
bool isHaveValue = result.valid();  // 可以通過這個函式來判斷是否有值
auto myValue = result_s.get();   // 這種寫法是複製語義,可以執行多次

二、原子操作 std::atomic

1、概述

    // 原子操作:可以理解成一種不需要用到互斥量技術的多執行緒併發變成方式
    // 原子操作:是在多執行緒中不會被打斷的程式執行片段
    // 原子操作效率比互斥量效率上更好
    // 互斥量加鎖一般是一個程式碼段,原子操作一般針對的是一個變數
    // 原子操作一般指“不可分割的操作”,操作狀態要麼是完成的,要麼是未完成的,不會出現半完成狀態

2、原子操作演示

int m_Int = 0;
std::mutex m_mutex;
std::atomic<int> m_automicInt = 0;    // std::atomic   類模板,是用來封裝某個型別的值
// 封裝了一個型別為int的物件,我們可以像操作一個int型別變數一樣操作該值


// 假設多個執行緒的入口函式都是這個函式,
// 表示多個執行緒,都在改變m_int的值,則需要通過加鎖技術來保證結果的正確性
void WriteIntValue()
{
    for (int i = 0; i < 10000; ++i)
    {
        m_automicInt++;  // 對應的操作是個原子操作,所以不會被打斷
        // 如果此處用的是普通的int 型別,則需要加鎖來執行
        //m_mutex.lock();
        //m_Int++;
        //m_mutex.unlock();
        m_automicInt += 1; // 結果正確
        m_automicInt = m_automicInt + 1;  // 結果錯誤:說明不是所有運算子都支援原子操作
        // 原子操作一般支援: ++  --  +=  &=  |=  ^= 這些運算子,其他可能不支援
    }
}