C++多線程框架


Thread線程框架

線程定義:
線程可以理解為一個特立獨行的函數。其存在的意義,就是並行,避免了主線程的阻塞。

----------------------------thread與函數----------------------------------

線程啟動

  C++線程的啟動, 只需要#include <thread>即可。 線程對象的創建, 意味着線程的開始。

1)同步

#include <iostream> #include <thread> #include <unistd.h> using namespace std; void func() { cout<<"thread id:"<<this_thread::get_id()<<endl; cout<<"do some work"<<endl; sleep(3); } int main() { cout<<"maint thread id:"<<this_thread::get_id()<<endl; thread t(func); t.join(); return 0; }

  t.join t.detach 標志着, 線程對象和線程的關系。 t.join 表示, 線程與線程對象的同步關系。 而 t.detach 表示, 線程與線程對象的異步關系。 在線程生成后,必須指定join或者detach狀態來。

  detach 后的線程,不能再 join,是否可以 join 可以通過 joinable 來判斷。 

2)異步

#include <iostream>
#include <memory>

using
namespace std; void func() { cout<<"thread id:"<<this_thread::get_id()<<endl; int i = 0; while(i++<5) { cout<<"assist thread running times:"<<i<<endl; sleep(1); } cout<<"----end assist thread work!------"<<endl; } int main() { cout<<"maint thread id:"<<this_thread::get_id()<<endl; thread t(func); // t.join(); //!同步 t.detach(); //!異步 int i =0; while(i++<10) { cout<<"main thread running times:"<<i<<endl; sleep(1); } cout<<"-----main thread finished!-----"<<endl; }

  在次線程detach的狀態下,要保證主線程的上聲明周期要比次線程聲明周期長,否則此線線程將中斷退出。

 

 

傳參方式

  線程有自己獨立的棧。可供享受全局的變量。在線程啟動的時候可以傳入啟動的參數。

#include <iostream> #include <thread> using namespace std; void func(int n, string s) { for(int i=0;i <n ;i++) { cout<<s<<endl; } } int main() { thread t(func,5,"china"); t.join(); return 0; }

  除了傳入參數,共享全局以外,還可以使用std::ref輔助傳入本地變量的引用。thread認為不加std::ref包裝的變量都是以拷貝的方式傳入線程中去的。

#include <iostream> #include <thread> using namespace std; void func(int &n, string &s) { for(int i=0;i <n ;i++) { cout<<s<<endl; } n = 10; s = "america"; } int main() { int n = 5; string s = "china"; // thread t(func,n, s); //!編譯不過,thread無法區分傳入的參數 thread t(func,ref(n), ref(s)); //!正確的傳引用的姿勢,應該采用std::ref來對變量包裝  t.join(); return 0; 

 

----------------------------thread與類成員函數-----------------------------------

  以上都是通過線程來包裝普通的函數。類的成員函數該如何引入線程呢?如下:

1)類外使用線程(推薦):

#include <iostream> #include <thread> using namespace std; class ThreadTest { public: ThreadTest() { cout<<"ThreadTest():"<<this<<endl; } void func() { int n = 0; cout<<"void func(int n):"<<this<<endl; while(n++<10) { cout<<"thread in class runtime:"<<n<<endl; } } ~ThreadTest() = default; }; int main() { ThreadTest test; thread t(&ThreadTest::func,test); t.join(); cout<<"Pls observe the difference between the two printed addresses!"<<endl;return 0; }

  這個函數執行起來顯然沒什么錯誤,但是有一個問題:我們構造時對象的內存地址居然與多線程中執行函數地址不一樣,要記住這可是該對象的成員函數啊?我們前面已經提到過,不使用std::ref傳入線程的變量默認都是以拷貝的方式傳入的兩次地址不一樣的原因就是如此!要想將該對象的成員函數加入線程,我們應該使用std::ref或者直接傳入對象的指針。

#include <iostream> #include <thread> using namespace std; class ThreadTest { public: ThreadTest() { cout<<"ThreadTest():"<<this<<endl; } void func() { int n = 0; cout<<"void func(int n):"<<this<<endl; while(n++<10) { cout<<"thread in class runtime:"<<n<<endl; } } ~ThreadTest() = default; }; int main() { ThreadTest test; // thread t(&ThreadTest::func,test); //!對象拷貝   thread t(&ThreadTest::func,std::ref(test));       //!傳入引用 // thread t(&ThreadTest::func,&test); //!傳入指針;  t.join(); cout<<"Please observe the difference between the two printed addresses!"<<endl;return 0; }

 

2)類內使用線程:

 

#include <iostream> #include <thread> using namespace std; class ThreadInClass { public: ThreadInClass(){cout<<"ThreadInClass():"<<this<<endl;} ~ThreadInClass() = default; void runThread() { thread t(&ThreadInClass::func,this); t.join(); // t.detach();//使用detach,同樣也要保證runThread的生存周期比t要長。  } void func() { int n = 0; cout<<"void func(int n):"<<this<<endl; while(n++<10){ cout<<"thread in class runtime:"<<n<<endl; } } }; int main() { ThreadInClass tic; tic.runThread(); }

 

 

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM