C++:多线程中的小白(1)基础概念
一直在聽別人說線程,進程,多線程等,覺得自己是知道的,其實上手后一灘爛泥啊.....
目錄
一、概念(并發、可執行程序、進程)
二、C++11新標準線程庫
一、概念(并發、可執行程序、進程)
1、并發:兩個或更多的任務(獨立的活動)同時發生(進行)。比如一邊唱歌一邊彈琴這個就是并發。我一個程序同時執行多個獨立的任務這個就是并發。
(以往的計算機只有一個CPU就是單核CPU(中央處理器),那么在某一時刻只能執行一個任務,那他是怎么實現同時執行多個任務的需求的呢?是這樣的:實現多任務的方式就是由操作系統調度,以每秒鐘為單位進行多次所謂的“任務切換”,(意思激就是比如說我有10個任務,第一個任務我做了10毫秒,然后我馬上切換到下個任務再做10毫秒,再切換到下個任務我在做10毫秒,切完之后我再切換回來執行第一個任務,第二個任務....就這么切著來,雖然我同一時刻只能做一個任務,但是我切的快啊,就好像這10個任務同時在執行一樣,實際上嚴格意義來說他不是同時的多任務,這只是一種叫并發的假想。這種切換也叫上下文切換,比如說我第一個任務運行到中途的時候我要切換到下一個任務,那我第一個任務在執行時我有一些變量啊入口啊等等,那我需要保存下來,那過一會我要重新執行第一個這個人物的時候我要恢復這些變量值,切換的時候我保存這些當前的局部變量等等我肯定有一些時間的開銷,那這種就屬于上下文切換的時間開銷,所以任務越多開銷的就越大,每一個任務都需要保存我離開時的當前狀態,以便我一會切換回來時恢復到我離開時的狀態,所以說切換上下文是要有時間開銷的(時間開銷包括,操作系統要保存你切換時的各種狀態,執行進度等信息都需要時間;一會切換回來的時候要復原這些信息)))
(但是隨著計算機硬件的發展,出現了多處理器計算機,用于服務器和高性能計算機領域;而且現在的臺式機在一塊芯片上有多核(多個)CPU,他們就能夠實現真正的并行執行多任務了(也就是概念硬件并發),比如我有4個核2個任務那剛好一個核執行一個任務但是如果我有4個核但是有8個任務,那不好意思你還得切)打開任務管理器就可以查看此時有多少個任務在執行 :
??
使用并發的原因:主要是為了同時可以干多個事情,提高性能。
實現并發的手段:
- 我們通過多個進程實現并發。
- 在單獨的進程中我構建多個線程,來實現并發。(自己寫代碼來實現除了主線程之外的其他線程)
- 多進程并發和多線程并發雖然可以混合使用,但是優先考慮多線程技術手段。而不是多進程。
- 多進程并發:比如說我啟動一個word用來打字,那么我這個word不就是一個進程嗎?那我再啟動一個瀏覽器觀看網頁,也是一個進程(啟動起來就是一個進程)
- 多線程并發:在單個進程中我創建了多個線程;每個線程都有自己獨立的運行路徑,但是一個進程中的所有線程共享地址空間(共享內存),你這個全局變量在各個線程之間都能用(全局變量指針引用都可以在線程之間傳遞),所以使用多線程開銷遠遠小于多進程。但是共享內存也帶來了新問題,就是數據一致性問題,(什么叫數據一致性問題呢,比如說你現在有兩個線程,A和B,比如說線程A要往一個內存寫數據,線程B在同一時刻也可能往這塊內存寫數據,那咱們就得采用技術手段讓他們有先后,總不能同時往這寫就寫亂套了啊可能會相互覆蓋掉)
2、可執行程序:(說白了就是磁盤上的一個文件)在windows下一個擴展名為.exe的就是一個可執行程序,雙擊他就會執行。在linux下ls -la,rwxrwxrwx(帶x的就是可執行權限)
3、進程:(大家已經知道可執行程序是能夠運行的,在windows下雙擊exe運行一下或者在vs里邊使用ctrlF5也是執行一個可執行程序;在linux下我們可以./文件名也可以運行一個可執行程序,既然他們可以運行起來那么我們這個進程的概念就出來了)進程指正在運行的程序(一個可執行程序運行起來了,這就叫創建了一個進程)。確切的來說,當一個程序進入內存運行,即變成一個進程,進程是處于運行過程中的程序,并且具有一定獨立功能。
(簡而言之:一個程序運行后至少有一個進程,一個進程中可以包含多個線程)
打開自己的任務管理器可以查看一下自己正在使用的進程有哪些?
也可以在用戶里邊查看當前正在運行的進程
4、線程:(每個進程都有一個主線程,只要這個進程運行起來了就有一個主線程;并且這個主線程是唯一的,一個進程中只能有一個主線程;當你執行這個可執行程序,產生了一個進程后這個主線程就隨著這個進程默默的啟動起來了,只要你這個進程存在了主線程就同時存在了;當你運行一個最簡單的main函數時,實際上是進程的這個主線程來執行(調用)這個main函數中的代碼,當main函數的代碼執行完了之后,主線程也就執行完了,主線程執行完了return出去了,整個這個進程也就運行結束了,所以說主線程的壽命是跟隨進程的壽命,你進程有多長我線程的壽命就有多長,你進程執行完了我主線程也就執行完了或者說我主線程執行結束了你進程也就結束了)(主線程不需要我們創建他就自然存在,從main函數開始)
線程是(線程是執行代碼的;線程這個東西理解成一條代碼的執行通路(道路))進程中的一個執行單元,負責當前進程中程序的執行,一個進程中至少有一個線程。一個進程中是可以有多個線程的,這個應用程序也可以稱之為多線程程序。
除了主線程之外我們可以通過自己寫代碼來創建其他的線程(當然你創建的其他線程他不叫主線程,主線程只有一個,是由系統自動幫我們創建的),其他線程他走的是別的道路(不應該走main這個道路,main這個道路是給主線程走的;其他線程甚至去不同的地方);我每創建一個新線程,我就可以在同一個時刻多干一個不同的事(多走一條不同的代碼代碼執行路徑);
5、多線程:(就是并發,同時干多個事情)即就是一個程序中有多個線程在同時執行。當然線程不是越多越好,每個線程都需要一個獨立的堆棧空間(大概消耗1M)(你整個物理內存才4G,4G的話也就代表你創建線程最多最多也就創建4千來個,你這4G內存就吃光了,而且這個還是理論值,你真的創建4千個多個線程嗎?那不可以,因為這個線程之間我這么多個線程我只有雙核或者4核CPU對吧,如果有幾千個任務的話我這么多個任務就需要在4個CPU之間來回的切換,上下文切換是有代價的,要保存很多中間狀態,那你線程很多上下文切換就會很頻繁,切換會耗費程序本該運行的時間)
單線程程序:即,若有多個任務只能依次執行。當上一個任務執行結束后,下一個任務開始執行。比如我正在聽歌,那么就不能同時寫字,只有聽歌這個過程結束了放下我才能開始寫字。
多線程程序:即,若有多個任務可以同時執行。可以一邊聽歌一邊寫字。
總結:和進程比線程有如下優點:
- 線程啟動速度更快,更輕量級(消耗資源少)。
- 系統資源開銷更少,執行速度更快,比如共享內存這種通訊方式,比任何其他的通信方式都快(這可是內存操作啊)。
缺點:
- 使用起來有一定難度,要小心處理數據的一致性問題
二、C++11新標準線程庫
以網寫多線程程序,這每個不同的操作系統平臺,他都有不同的多線程創建方法,或者說是要調用不同的系統函數,比如說在windows下有時候會用CreateThread()有時候用_beginthread()、_beginthreadex()創建線程;linux下會使用pthread_create()創建線程。還有一些概念:臨界區,互斥量等;所以在不同的平臺下創建的線程不一樣,以往的多線程代碼不能跨平臺編譯。
所以從C++11新標準開始,C++本身增加了對這個多線程的支持,(以往不是的,不是C++本身增加的,以往是通過操作系統提供的額外的接口)這就相當于我們可以使用C++語言本身來編寫和這個具體操作平臺無關的多線程程序了,意味著可移植性啊(也叫跨平臺了),這就大大減少開發人員工作量了。
?
?
?
?
總結
以上是生活随笔為你收集整理的C++:多线程中的小白(1)基础概念的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Socket:UDP协议小白
- 下一篇: PCL调错:(3)error C2589