天天看點

程序,線程,多線程程序,線程,多線程

程序,線程,多線程

程序與線程:

程序:具有一定獨立功能的程式關于某個資料集合上的一次運作活動,是系統進行資源配置設定和排程的一個獨立機關.      【占用資源的最小單元】

線程:它是比程序更小的能獨立運作的基本機關. 是程序的一個實體,是CPU排程和分派的基本機關。它隻擁有運作中必不可少的資源(如程式計數器,一組寄存器和棧),但它可與同屬一個程序的其他的線程共享程序所擁有的全部資源.             【排程的機關】  

關系:

(1)一個線程隻能屬于一個程序,而一個程序可以有多個線程,但至少有一個線程。

(2)一個線程可以建立和撤消另一個線程,同一程序中的多個線程之間可以并發執行。程序之間也可以并發執行.

(3)資源配置設定給程序,同一程序的所有線程共享該程序的所有資源。

(4)處理機分給線程,即真正在處理機上運作的是線程。

(5)線程在執行過程中,需要協作同步。不同程序的線程間要利用消息通信的辦法實作同步。

差別:

(1)  擁有資源和排程:程序是擁有資源的獨立機關,線程不擁有系統資源,但可以通路隸屬于程序的資源。線程是指程序内的一個執行單元,是排程和配置設定的基本機關,

(2)  通信:線程之間的通信比較友善。統一程序下的線程共享資料(比如全局變量,靜态變量),通過這些資料來通信,快捷友善,但要處理好這些通路的同步與互斥。而程序之間的通信隻能通過程序通信的方式進行(如管道,信号,消息隊列,共享記憶體,信号量,套接字)。

(3)  執行:每個獨立的線程有自己的一個程式入口,順序執行序列和程式的出口,但是不能獨立執行,必須依附與程式之中,由應用程式提供多個線程的并發控制。

(4)  系統開銷:程序有獨立的位址空間,在建立或撤消程序時,系統都要為之配置設定和回收資源,導緻開銷明顯大。運作一個程序中的線程,共享大部分資料,使用相同的位址空間,是以啟動一個線程,切換一個線程遠比程序操作要快,花費也要小得多。

(5)  健壯性:多程序的程式要比多線程的程式健壯。程序有獨立的位址空間,一個程序崩潰後,在保護模式下不會對其它程序産生影響。而線程隻是一個程序中的不同執行路徑,有自己的堆棧和局部變量,但線程之間沒有單獨的位址空間,一個線程死掉就等于整個程序死掉。

線程安全:

   多線程的程式運作結果是可預期的,而且與單線程的程式運作結果一樣。

線程狀态:

就緒、運作、阻塞、挂起阻塞、挂起就緒

多線程:

1.    多線程互斥與同步有幾種實作方法?都是什麼?

臨界區(CS:critical section)、互斥量(Mutex);事件(Event)、信号量(semaphores)。

a.    臨界區(同一個程序内,實作互斥): 在任意時刻隻允許一個線程對共享資源進行通路,其他的被挂起,直到臨界區被釋放。【多線程的串行化,速度快,适合控制資料通路】

b.    互斥量(可以跨程序,實作互斥):隻有擁有互斥對象(隻有一個)的線程才具有通路資源的權限,目前占據資源的線程在任務處理完後應将擁有的互斥對象交出,以便其他線程在獲得後得以通路資源。【為協調對一個共享資源的單獨通路而設計】

###  臨界區 VS  互斥量 :

   兩者都可以用于同一程序中不同子線程對資源的互斥通路。互斥量可以很好的解決由于線程意外終止資源無法釋放的問題。互斥量是核心對象,可以命名,也就是說它可以跨程序使用,是以建立互斥量需要的資源更多。在程序内部,使用臨界區會更快。

c.    事件(實作同步,可以跨程序):用來通知線程有一些事件已發生,進而啟動後繼任務的開始。

d.    信号量(主要是實作同步,可以跨程序): 它允許多個線程在同一時刻通路同一資源,但是需要限制在同一時刻通路此資源的最大線程數目。一般是将目前可用資源計數設定為最大資源計數,每增加一個線程對共享資源的通路,目前可用資源計數就會減1,隻要目前可用資源計數是大于0的,就可以發出信号量信号。【為控制一個具有有限數量使用者資源而設計】

線程間的同步方法大體可分為兩類:使用者模式和核心模式。顧名思義,核心模式就是指利用系統核心對象的單一性來進行同步,使用時需要切換核心态與使用者态,而使用者模式就是不需要切換到核心态,隻在使用者态完成操作。

使用者模式下的方法有:原子操作(例如一個單一的全局變量),臨界區。核心模式下的方法有:事件,信号量,互斥量。

2.    C++中多線程實作方法:

C++ 11新特性中,可以使用std::thread來建立線程。Windows系統提供了相關API,我們可以使用他們來進行多線程程式設計。

例子

http://www.cnblogs.com/codingmengmeng/p/5913068.html

線程随機交替運作,運作時間不一樣,可能主線程運作完之後将所占資源都釋放掉了,使得子線程還沒有運作完。    【可用sleep()】

注意程序之間會被打斷。如:

cout << "Main Thread Display!" <<endl;改成cout << "Main ThreadDisplay!\n";

【用互斥量(Mutex)來進行線程同步,允許一個線程擁有對共享資源的獨占。】

3.    多線程同步和互斥有何異同,在什麼情況下分别使用他們?舉例說明

同步,指線程之間所具有的一種制約關系,一個線程的執行依賴另一個線程的消息,當它沒有得到另一個線程的消息時應等待,直到消息到達時才被喚醒。

互斥,指對于共享的程序系統資源,在各單個線程通路時的排它性。線程互斥可以看成是一種特殊的線程同步。”不能同時通路,是個順序問題“。

舉例,設有一個全局變量global,為了保證線程安全,我們規定隻有當主線程修改了global之後下一個子線程才能通路global,這就需要同步主線程與子線程,可用關鍵段實作。當一個子線程通路global的時候另一個線程不能通路global,那麼就需要互斥。

4.    程式設計練習

參考:

http://blog.csdn.net/yaosiming2011/article/details/44280797

https://www.cnblogs.com/wuchanming/p/3992395.html?utm_source=tuicool&utm_medium=referral

http://www.cnblogs.com/xilentz/archive/2012/11/13/2767317.html

繼續閱讀