工作中,我們會遇到這樣一種場景,就是某個函數,是被外部調用的,而且要求這個被調用的函數不能阻塞,不能太耗時,否則會影響外部的正常調用。
比如,示例中的TestA函數,它是被外部調用的,而且是一個耗時的操作,它還修改了外部的其他變量。
這時候,需要用線程來解耦,避免TestA函數因爲太過耗時而阻塞。
因爲改變了外部變量,因此匿名函數還用到了 引用 作爲參數。
這裏用到匿名函數,主要是 有些時候不需要單獨再去寫一個函數 來包裝一些操作。
都丟到匿名函數裏面,作爲參數,傳遞個一個 thread 的對象,在創建對象的時候就會去執行。
關鍵代碼就是標紅色的這部分,用匿名函數寫法會比較簡潔。
線程對象 + 匿名函數,實現了 TestA 方法的非阻塞調用。
場景限制:如果 TestA 調用非常頻繁(每3秒1次不算頻繁,每秒幾次就頻繁了),那麼這種方法就不適用了。因爲頻繁的申請線程資源,會增加服務器負載,影響性能。
那種情況就要考慮其他方式來解決函數阻塞的情況了。比如C++的協程,用異步方式來執行。不過C++協程語法比較複雜,可以參考ts的協程語法來理解協程。
#include <iostream> #include <string> #include <vector> #include <thread> using namespace std; //g++ main.cpp --std=c++11 -lpthread -o a.bin // 用線程+匿名函數,解決 函數阻塞問題.此處的 TestA 函數是非阻塞的 void TestA(int& A, int & B) { cout <<"11 --- A:"<<A<<"|B:"<<B<<endl<<flush; // 弄一個線程,detach thread th( [&]{ //1.比較耗時的操作 //2.修改了外部變量 A=3; B=4; this_thread::sleep_for(chrono::seconds(3));//1000ms cout <<"44 --- A:"<<A<<"|B:"<<B<<endl<<flush; } ); th.detach(); cout <<"22 --- A:"<<A<<"|B:"<<B<<endl<<flush; } // g++ main.cpp --std=c++11 -lpthread int main() { // 外部的2個變量 int A1 = 1; int B1 = 2; TestA(A1, B1);// TestA 會改變外部參數 cout <<"33 --- A:"<<A1<<"|B:"<<B1<<endl<<flush; this_thread::sleep_for(chrono::seconds(8));//1000ms cout <<"55 --- A:"<<A1<<"|B:"<<B1<<endl<<flush; cout <<"-------hello end! -------"<<endl<<flush; return 0; }
執行情況:
[[email protected] demo3]$ g++ main.cpp --std=c++11 -lpthread -o a.bin [[email protected] demo3]$ [[email protected] demo3]$ [[email protected] demo3]$ ./a.bin 11 --- A:1|B:2 22 --- A:1|B:2 33 --- A:1|B:2 44 --- A:3|B:4 55 --- A:3|B:4 -------hello end! -------