一:併發、進程的基本概念
併發,線程進程要求必須掌握;
(1.1)併發
兩個或者更多任務(獨立的活動)同時發生(進行):一個程序同時執行多個獨立的任務
以前計算機單核cpu(中央處理器)某一時刻只能執行一個任務:由操作系統調度,每秒鐘進行多次所謂的任務切換。
併發的假象(不是正真的併發);這種切換(上下文切換)是有時間開銷的,比如操作系統要保存你切換時的各種狀態。
執行進度等信息,都需要時間,一會切換回來的時候需要回復這些信息。
硬件發展,出現了多處理器計算機:用於服務器和高性能計算領域。
臺式機:在一塊芯片上有多核(多個)cpu:雙核,四核,8核...
這時就能夠正真的執行多任務(硬件併發);
使用併發的原因:主要就是同時可以幹多個事,提高性能;
(1.2)可執行程序
磁盤上的一個文件,windows下,一個擴展名爲.exe的。
linux下ls -la 有 rwxrwxrwx 可執行權限。
(1.3)進程:可執行程序是可以運行的
windows下,雙擊一個可執行程序來運行
linux下 ./文件名 ./a;
一個可執行程序運行起來了,叫做創建了一個進程;
進程就是一個運行起來的可執行程序;
(1.4)線程:
a)每個進程(執行起來的可執行程序),都有一個主線程,這個主線程是唯一的,也就是一個進程中只能有一個主線程。
b)當你執行一個可執行程序,產生一個進程後,這個主線程就隨着這個進程默默的啓動起來了。
實際上運行這個程序的時候,實際上是進程的主線程來執行(調用)這個main函數中的代碼;
線程與進程脣齒相依,你中有我,我中有你。
線程:就是用來執行代碼的。
線程這個東西可以理解成,一條代碼的執行通路。
除了主線程之外,我們可以通過自己寫代碼來創建其它線程,其它線程走的是別的道路。完成不同的目的
每創建一個新線程,我就可以在同一時刻,多幹一個不同的事(多走一條不同的代碼執行路徑)
多線程(併發)
線程並不是越多越好,每個線程買都需要一個獨立的堆棧空間,線程間的切換需要保存很多中間狀態;
會耗費本該屬於程序運行的時間;
總結線程:
線程是用來執行代碼的;
把線程這個東西理解成一條代碼的執行通路,一個新線程代表一條新的通路。
一個進程自動包含一個主線程,主線程隨着進程默默的啓動並運行,我們可以通過編代碼來創建其他線程(非主線程)
但是創建的數量不建議超過200~300個,至於多少個合適,需要根據實際情況優化。
因爲主線程是自動啓動的,所以一個進程中最少有一個線程(主線程)進程和線程感覺就是地位和兒子的關係
說白了:多線程程序可以同時幹多個事,所以運行效率比較高,但是到底有多高,並不是一個很容易評估和量化的東西。
大家仍舊需要在實際項目中調整和優化;
(1.5)學習心得
開發多線程程序:是高級程序員的必備技能。
c++線程會涉及比較多的新概念,對於拿高薪特別關鍵,不要急於求成。
二:併發的實現方法
兩個或者更多的任務(獨立的活動)同時發生(進行)
實現併發的手段:
a)我們通過多個進程實現併發。
b)在單獨的進程中,我創建多個線程來實現併發;自己寫代碼來創建除了主線程之外的其它線程;
(2.1)多進程併發
word啓動後就是一個進程,ie瀏覽器啓動後就是一個進程
賬號服務器,遊戲邏輯服務器,服務器進程之間的通信。
進程之間的通信(同一個電腦上:管道,文件,消息隊列,共享內存);
不同電腦上:socket通信技術;
(2.2)多線程併發:單個進程中,創建了多個線程。
線程:感覺像輕量級的進程,每個線程都有自己獨立的運行路徑,但是一個進程中的所有線程共享地址空間(共享內存);
全局變量,指針,引用都可以在線程中傳遞,所以:使用多線程開銷遠遠小於多進程。
共享內存帶來新問題,數據一致性問題:線程A,線程B;
多進程併發和多線程併發雖然可以混合使用,但是老師建議,優先考慮多線程技術,而不是多進程;
本文中主要是講多線程併發。
(2.3)總結:
和進程比,線程有如下優點:
(1)線程啓動速度更快,更輕量級;
(2)系統資源開銷更少,執行速度更快,比如共享內存這種通信方式比其他任何通信方式都快。
缺點
(a)使用有一定的難度,需要小心處理數據的一致性問題。
三:c++11 標準線程庫
windows: CreateThread(), _beginthread(),_beginthreadex()創建線程
linux: pthread_create()創建線程
臨界區,互斥量;
以往的多線程代碼不能跨平臺;
POSIX thread(pthread);跨平臺;但是需要做一番配置,所以用起來它也不是那麼方便。
從c++11 新標準,c++語言本身增加對多線程的支持,意味着可移植性(跨平臺);這就大大減少開發人員的工作量。