溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

并發(fā)編程專題(一)-并發(fā)與多線程

發(fā)布時(shí)間:2020-08-29 11:55:23 來(lái)源:網(wǎng)絡(luò) 閱讀:730 作者:BRUCELIU9527 欄目:編程語(yǔ)言
1.并發(fā)
1.1 并發(fā)與并行

首先介紹一下并發(fā)與并行,兩者雖然只有一字之差,但實(shí)際上卻有著本質(zhì)的區(qū)別,其概念如下:

  • 并行性(parallel):指在同一時(shí)刻,有多條指令在多個(gè)處理器上同時(shí)執(zhí)行;
  • 并發(fā)性(concurrency):指在同一時(shí)刻只能有一條指令執(zhí)行,但多個(gè)進(jìn)程指令被快速輪換執(zhí)行,使得在宏觀上具有多個(gè)進(jìn)程同時(shí)執(zhí)行的效果。

并發(fā)編程專題(一)-并發(fā)與多線程

在操作系統(tǒng)中,安裝了多個(gè)程序,并發(fā)指的是在一段時(shí)間內(nèi)宏觀上有多個(gè)程序同時(shí)運(yùn)行,這在單 CPU 系統(tǒng)中,每一時(shí)刻只能有一道程序執(zhí)行,即微觀上這些程序是分時(shí)的交替運(yùn)行,只不過(guò)是給人的感覺(jué)是同時(shí)運(yùn)行,那是因?yàn)榉謺r(shí)交替運(yùn)行的時(shí)間是非常短的。

而在多個(gè) CPU 系統(tǒng)中,則這些可以并發(fā)執(zhí)行的程序便可以分配到多個(gè)處理器上(CPU),實(shí)現(xiàn)多任務(wù)并行執(zhí)行,即利用每個(gè)處理器來(lái)處理一個(gè)可以并發(fā)執(zhí)行的程序,這樣多個(gè)程序便可以同時(shí)執(zhí)行。目前電腦市場(chǎng)上說(shuō)的多核 CPU,便是多核處理器,核越多,并行處理的程序越多,能大大的提高電腦運(yùn)行的效率。
并發(fā)編程專題(一)-并發(fā)與多線程

注意:?jiǎn)魏颂幚砥鞯挠?jì)算機(jī)肯定是不能并行的處理多個(gè)任務(wù)的,只能是多個(gè)任務(wù)在單個(gè)CPU上并發(fā)運(yùn)行。同理,線程也是一樣的,從宏觀角度上理解線程是并行運(yùn)行的,但是從微觀角度上分析卻是串行運(yùn)行的,即一個(gè)線程一個(gè)線程的去運(yùn)行,當(dāng)系統(tǒng)只有一個(gè)CPU時(shí),線程會(huì)以某種順序執(zhí)行多個(gè)線程,我們把這種情況稱之為線程調(diào)度。

1.2 順序編程與并發(fā)編程

我們?cè)诮鉀Q編程問(wèn)題時(shí),通常使用順序編程來(lái)解決,即程序中的所有事物在任意時(shí)刻都只能執(zhí)行一個(gè)步驟。然而對(duì)于某些問(wèn)題,我們希望能夠并行地執(zhí)行程序中的多個(gè)部分,來(lái)達(dá)到我們想要的效果。在單處理器機(jī)器中,我們可以將程序劃分為多個(gè)部分,然后每個(gè)部分由該處理器并發(fā)執(zhí)行。在多處理器機(jī)器中,我們可以將程序劃分多個(gè)部分,然后每個(gè)部分分別在多個(gè)處理器上并行執(zhí)行。當(dāng)然為了更加充分利用CPU資源,我們也可以在多個(gè)處理器上并發(fā)執(zhí)行,那么在這我們就涉及到了另一種編程模式了并發(fā)編程。并發(fā)編程又叫多線程編程。并發(fā)編程使我們可以將程序劃分為多個(gè)分離的、獨(dú)立運(yùn)行的任務(wù)。通過(guò)使用多線程機(jī)制,每個(gè)獨(dú)立任務(wù)都將由線程來(lái)驅(qū)動(dòng)。一個(gè)線程就是在進(jìn)程中的一個(gè)單一的順序控制流,單個(gè)進(jìn)程可以擁有多個(gè)"并發(fā)執(zhí)行"的任務(wù)。這樣使程序的每個(gè)任務(wù),都好像擁有一個(gè)自己的CPU一樣。但其底層機(jī)制還是是切分CPU時(shí)間,CPU都有個(gè)時(shí)鐘頻率,表示每秒中能執(zhí)行CPU指令的次數(shù)。在每個(gè)時(shí)鐘周期內(nèi),CPU實(shí)際上只能去執(zhí)行一條也有可能多條指令。操作系統(tǒng)將進(jìn)程進(jìn)行管理,輪流分配每個(gè)進(jìn)程很短的一段是時(shí)間但不一定是均分,然后在每個(gè)進(jìn)程內(nèi)部,程序代碼自己處理該進(jìn)程內(nèi)部線程的時(shí)間分配,多個(gè)線程之間相互的切換去執(zhí)行,這個(gè)切換時(shí)間也是非常短的所以通常我們不需要考慮它。

并發(fā)是指"發(fā)",不是處理,最常見(jiàn)的情況就是許多人在一小段時(shí)間內(nèi)都點(diǎn)擊了你的網(wǎng)站,發(fā)出了處理請(qǐng)求。并發(fā)編程是對(duì)并發(fā)狀況的應(yīng)對(duì),在單處理器和多處理器機(jī)器上都可對(duì)其進(jìn)行應(yīng)對(duì),可這個(gè)處理方案和架構(gòu)以及算法有關(guān)。CPU一般是分時(shí)的,會(huì)在極短的時(shí)間內(nèi)不停地切換給不同的線程使用,無(wú)論多少并發(fā)都會(huì)處理下去,只是時(shí)間問(wèn)題,如何提高處理效率就看采用的技術(shù)了。

1.3 并發(fā)編程的優(yōu)勢(shì)

如果使用得當(dāng),線程可以有效地降低程序的開(kāi)發(fā)和維護(hù)等成本,同時(shí)提升復(fù)雜應(yīng)用程序的性能。具體說(shuō),線程的優(yōu)勢(shì)有:

  • 發(fā)揮多處理器的強(qiáng)大能力
    現(xiàn)在,多處理器系統(tǒng)正日益盛行,并且價(jià)格不斷降低,即時(shí)在低端服務(wù)器和中斷桌面系統(tǒng)中,通常也會(huì)采用多個(gè)處理器,這種趨勢(shì)還在進(jìn)一步加快,因?yàn)橥ㄟ^(guò)提高時(shí)鐘頻率來(lái)提升性能已變得越來(lái)越困難,處理器生產(chǎn)廠商都開(kāi)始轉(zhuǎn)而在單個(gè)芯片上放置多個(gè)處理器核。試想,如果只有單個(gè)線程,雙核處理器系統(tǒng)上程序只能使用一半的CPU資源,擁有100個(gè)處理器的系統(tǒng)上將有99%的資源無(wú)法使用。多線程程序則可以同時(shí)在多個(gè)處理器上執(zhí)行,如果設(shè)計(jì)正確,多線程程序可以通過(guò)提高處理器資源的利用率來(lái)提升系統(tǒng)吞吐率。

    • 在單處理器系統(tǒng)上獲得更高的吞吐率
      如果程序是單線程的,那么當(dāng)程序等待某個(gè)同步I/O操作完成時(shí),處理器將處于空閑狀態(tài)。而在多線程程序中,如果一個(gè)線程在等待I/O操作完成,另一個(gè)線程可以繼續(xù)運(yùn)行,使得程序能在I/O阻塞期間繼續(xù)運(yùn)行。

    • 建模的簡(jiǎn)單性
      通過(guò)使用線程,可以將復(fù)雜并且異步的工作流進(jìn)一步分解為一組簡(jiǎn)單并且同步的工作流,每個(gè)工作流在一個(gè)單獨(dú)的線程中運(yùn)行,并在特定的同步位置進(jìn)行交互。我們可以通過(guò)一些現(xiàn)有框架來(lái)實(shí)現(xiàn)上述目標(biāo),例如Servlet和RMI,框架負(fù)責(zé)解決一些細(xì)節(jié)問(wèn)題,例如請(qǐng)求管理、線程創(chuàng)建、負(fù)載平衡,并在正確的時(shí)候?qū)⒄?qǐng)求分發(fā)給正確的應(yīng)用程序組件。編寫Servlet的開(kāi)發(fā)人員不需要了解多少請(qǐng)求在同一時(shí)刻要被處理,也不需要了解套接字的輸入流或輸出流是否被阻塞,當(dāng)調(diào)用Servlet的service方法來(lái)響應(yīng)Web請(qǐng)求時(shí),可以以同步的方式來(lái)處理這個(gè)請(qǐng)求,就好像它是一個(gè)單線程程序。

    • 異步事件的簡(jiǎn)化處理
      服務(wù)器應(yīng)用程序在接受多個(gè)來(lái)自遠(yuǎn)程客戶端的套接字連接請(qǐng)求時(shí),如果為每個(gè)連接都分配其各自的線程并且使用同步I/O,那么就會(huì)降低這類程序的開(kāi)發(fā)難度。如果某個(gè)應(yīng)用程序?qū)μ捉幼謭?zhí)行讀操作而此時(shí)還沒(méi)有數(shù)據(jù)到來(lái),那么這個(gè)讀操作將一直阻塞,直到有數(shù)據(jù)到達(dá)。在單線程應(yīng)用程序中,這不僅意味著在處理請(qǐng)求的過(guò)程中將停頓,而且還意味著在這個(gè)線程被阻塞期間,對(duì)所有請(qǐng)求的處理都將停頓。為了避免這個(gè)問(wèn)題,單線程服務(wù)器應(yīng)用程序必須使用非阻塞I/O,但是這種I/O的復(fù)雜性要遠(yuǎn)遠(yuǎn)高于同步I/O,并且很容易出錯(cuò)。然而,如果每個(gè)請(qǐng)求都擁有自己的處理線程,那么在處理某個(gè)請(qǐng)求時(shí)發(fā)生的阻塞將不會(huì)影響其他請(qǐng)求的處理。

      在實(shí)際應(yīng)用中,多線程是非常有用的,一個(gè)瀏覽器必須能同時(shí)下載多個(gè)圖片;一個(gè)Web服務(wù)器必須能同時(shí)響應(yīng)多個(gè)用戶請(qǐng)求;Java虛擬機(jī)本身就在后臺(tái)提供了一個(gè)超級(jí)線程來(lái)進(jìn)行垃圾回收;圖形用戶界面(GUI)應(yīng)用也需要啟動(dòng)單獨(dú)的線程從主機(jī)環(huán)境收集用戶界面事件……總之,多線程在實(shí)際編程中的應(yīng)用是非常廣泛的。

2.進(jìn)程和線程
  • 進(jìn)程:是指一個(gè)內(nèi)存中運(yùn)行的應(yīng)用程序,每個(gè)進(jìn)程都有一個(gè)獨(dú)立的內(nèi)存空間,一個(gè)應(yīng)用程序可以同時(shí)運(yùn)行多個(gè)進(jìn)程;進(jìn)程也是程序的一次執(zhí)行過(guò)程,是系統(tǒng)運(yùn)行程序的基本單位;系統(tǒng)運(yùn)行一個(gè)程序即是一個(gè)進(jìn)程從創(chuàng)建、運(yùn)行到消亡的過(guò)程。進(jìn)程可以理解為受操作系統(tǒng)管理的基本運(yùn)行單元。360瀏覽器是一個(gè)進(jìn)程、WPS也是一個(gè)進(jìn)程,正在操作系統(tǒng)中運(yùn)行的".exe"都可以理解為一個(gè)進(jìn)程。

并發(fā)編程專題(一)-并發(fā)與多線程

  • 線程:線程是進(jìn)程中的一個(gè)執(zhí)行單元,負(fù)責(zé)當(dāng)前進(jìn)程中程序的執(zhí)行,一個(gè)進(jìn)程中至少有一個(gè)線程。一個(gè)進(jìn)程中是可以有多個(gè)線程的,這個(gè)應(yīng)用程序也可以稱之為多線程程序。
    進(jìn)程中獨(dú)立運(yùn)行的子任務(wù)就是一個(gè)線程。像QQ.exe運(yùn)行的時(shí)候就有很多子任務(wù)在運(yùn)行,比如聊天線程、好友視頻線程、下載文件線程等等。
    并發(fā)編程專題(一)-并發(fā)與多線程
    簡(jiǎn)而言之:一個(gè)程序運(yùn)行后至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程中可以包含多個(gè)線程。

    3.多任務(wù)、多進(jìn)程、多線程

    幾乎所有的操作系統(tǒng)都支持同時(shí)運(yùn)行多個(gè)任務(wù),一個(gè)任務(wù)通常就是一個(gè)程序,每個(gè)運(yùn)行中的程序就是一個(gè)進(jìn)程。當(dāng)一個(gè)程序運(yùn)行時(shí),內(nèi)部可能包含了多個(gè)順序執(zhí)行流,每個(gè)順序執(zhí)行流就是一個(gè)線程。

    3.1 多進(jìn)程

    實(shí)現(xiàn)并發(fā)最直接的方式是在操作系統(tǒng)級(jí)別使用進(jìn)程,進(jìn)程是運(yùn)行在它自己的地址空間內(nèi)的自包容的程序。多任務(wù)操作系統(tǒng)可以通過(guò)周期性地將CPU從一個(gè)進(jìn)程切換到另一個(gè)進(jìn)程,來(lái)實(shí)現(xiàn)同時(shí)運(yùn)行多個(gè)進(jìn)程。 盡管對(duì)于一個(gè)CPU而言,它在某個(gè)時(shí)間點(diǎn)只能運(yùn)行一個(gè)進(jìn)程,但CPU可以在多個(gè)進(jìn)程之間進(jìn)行輪換執(zhí)行,并且CPU的切換速度極高,使我們無(wú)法感知其切換的過(guò)程,就好像有多個(gè)進(jìn)程在同時(shí)執(zhí)行。
    幾乎所有的操作系統(tǒng)都支持進(jìn)程的概念,所有運(yùn)行中的任務(wù)通常對(duì)應(yīng)一個(gè)進(jìn)程(Process)。當(dāng)一個(gè)程序進(jìn)入內(nèi)存運(yùn)行時(shí),即變成一個(gè)進(jìn)程。進(jìn)程是處于運(yùn)行過(guò)程中的程序,并且具有一定的獨(dú)立功能,進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位。一般而言,進(jìn)程包含如下3個(gè)特征。

獨(dú)立性:進(jìn)程是系統(tǒng)中獨(dú)立存在的實(shí)體,它可以擁有自己獨(dú)立的資源,每一個(gè)進(jìn)程都擁有自己私有的地址空間。在沒(méi)有經(jīng)過(guò)進(jìn)程本身允許的情況下,一個(gè)用戶進(jìn)程不可以直接訪問(wèn)其他進(jìn)程的地址空間。
動(dòng)態(tài)性:進(jìn)程與程序的區(qū)別在于,程序只是一個(gè)靜態(tài)的指令集合,而進(jìn)程是一個(gè)正在系統(tǒng)中活動(dòng)的指令集合。在進(jìn)程中加入了時(shí)間的概念,進(jìn)程具有自己的生命周期和各種不同的狀態(tài),這些概念在程序中部是不具備的。
并發(fā)性:多個(gè)進(jìn)程可以在單個(gè)處理器上并發(fā)執(zhí)行,多個(gè)進(jìn)程之間不會(huì)互相影響。

3.2 多線程
3.2.1 多線程概述

多線程則擴(kuò)展了多進(jìn)程的概念。使得同一個(gè)進(jìn)程中也可以同時(shí)并發(fā)處理多個(gè)任務(wù)。線程(Thread)也被稱作輕量級(jí)進(jìn)程(Lightweight Process)。線程是進(jìn)程的執(zhí)行單元,就像進(jìn)程在操作系統(tǒng)中的地位一樣,線程在程序中是獨(dú)立的、并發(fā)的執(zhí)行流。當(dāng)進(jìn)程被初始化后,主線程就被創(chuàng)建了。對(duì)于絕大多數(shù)的應(yīng)用程序來(lái)說(shuō),通常僅要求有一個(gè)主線程,但也可以在該進(jìn)程內(nèi)創(chuàng)建多條順序執(zhí)行流,這些順序執(zhí)行流就是線程,每個(gè)線程也是互相獨(dú)立的。

線程是進(jìn)程的組成部分,一個(gè)進(jìn)程可以擁有多個(gè)線程,一個(gè)線程必須有一個(gè)父進(jìn)程。線程可以擁有自己的堆棧、自己的程序計(jì)數(shù)器和自己的局部變量,但不擁有系統(tǒng)資源,它與父進(jìn)程的其他線程共享該進(jìn)程所擁有的全部資源。因?yàn)槎鄠€(gè)線程共享父進(jìn)程里的全部資源,因此編程更加方便;但必須更加小心,我們必須確保線程不會(huì)妨礙同一進(jìn)程里的其他線程。

3.2.2 多線程機(jī)制

線程模型為編程帶來(lái)了便利,它簡(jiǎn)化了在單一程序中同時(shí)交織在一起的多個(gè)操作的處理。在使用線程時(shí),CPU將輪流給每個(gè)任務(wù)分配其占用時(shí)間。每個(gè)任務(wù)都覺(jué)得自己在一直占用CPU,但事實(shí)上CPU時(shí)間是劃分成片段分配給了所有的任務(wù)。線程的一大好處是可以使你從這個(gè)層次抽身出來(lái),即代碼不必知道它是運(yùn)行在具有一個(gè)還是多個(gè)CPU的機(jī)器上。所以,使用線程機(jī)制是一種建立透明的、可擴(kuò)展的程序的方法,如果程序行得太慢,為機(jī)器增添一個(gè)CPU就能很容易地加快程序的運(yùn)行速度。多任務(wù)和多線程往往是使用多處理器系統(tǒng)的最合理方式。

3.2.3 多線程調(diào)度

線程可以完成一定的任務(wù),可以與其他線程共享父進(jìn)程中的共享變量及部分環(huán)境,相互之間協(xié)同來(lái)完成進(jìn)程所要完成的任務(wù)。線程是獨(dú)立運(yùn)行的,它并不知道進(jìn)程中是否還有其他線程存在,線程的執(zhí)行是搶占式的,也就是說(shuō),當(dāng)前運(yùn)行的線程在任何時(shí)候都可能被掛起,以便另外一個(gè)線程可以運(yùn)行。

一個(gè)線程可以創(chuàng)建和撤銷另一個(gè)線程,同一個(gè)進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行。從邏輯角度來(lái)看,多線程存在于一個(gè)應(yīng)用程序中,讓一個(gè)應(yīng)用程序中可以有多個(gè)執(zhí)行部分同時(shí)執(zhí)行,但操作系統(tǒng)無(wú)須將多個(gè)線程看作多個(gè)獨(dú)立的應(yīng)用,對(duì)多線程實(shí)現(xiàn)調(diào)度和管理以及資源分配。線程的調(diào)度和管理由進(jìn)程本身負(fù)責(zé)完成。

納起采可以這樣說(shuō):操作系統(tǒng)可以同時(shí)執(zhí)行多個(gè)任務(wù),每個(gè)任務(wù)就是進(jìn)程;進(jìn)程可以同時(shí)執(zhí)行多個(gè)任務(wù),每個(gè)任務(wù)就是線程。簡(jiǎn)而言之,一個(gè)程序運(yùn)行后至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程里可以包含多個(gè)線程,但至少要包含一個(gè)線程。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI