線程知識

●多進程和多線程的區別

進程它是具有獨立地址空間的,優點就是隔離度好,穩定,因爲它是操作系統管理的,進程和進程之間是邏輯隔離的,只要操作系統不出問題的話,一個進程的錯誤一般不會影響到其它進程,缺點就是信息資源共享麻煩。而線程只是進程啓動的執行單元,它是共享進程資源的,創建銷燬、切換簡單,速度很快,佔用內存少,CPU利用率高。但是需要程序員管控的東西也比較多,相互影響出問題的機率較大,一個線程掛掉將導致整個進程掛掉,所以從程序員的角度來講,我們只能看到某種代碼是線程安全的,而沒有說進程安全的。

●在進程和線程上,應該怎麼選擇

我們平時在寫代碼的時候一般使用線程會比較多,像需要頻繁創建銷燬的,要處理大量運算、數據,又要能很好的顯示界面和及時響應消息的優先選擇多線程,因爲像這些運算會消耗大量的CPU,常見的有算法處理和圖像處理。還有一些操作允許併發而且有可能阻塞的, 也推薦使用多線程. 例如SOCKET, 磁盤操作等等。進程一般來說更穩定,而且它是內存隔離的,單個進程的異常不會導致整個應用的崩潰,方便調試,像很多服務器默認是使用進程模式的。

●線程之間是如何通信的

一個是使用全局變量進行通信,還有就是可以使用自定義的消息機制傳遞信息。其實因爲各個線程之間它是共享進程的資源的,所以它沒有像進程通信中的用於數據交換的通信方式,它通信的主要目的是用於線程同步,所以像一些互斥鎖啊臨界區啊CEvent事件對象和信號量對象都可以實現線程的通信和同步。

●進程之間是如何通信的

進程間的通信方式有PIPE管道,信號量,消息隊列,共享內存,還可以通過 socket套接字進行通信。根據信息量大小的不同可以分爲低級通信和高級通信,在選擇上,如果用戶傳遞的信息較少.或是需要通過信號來觸發某些行爲的,一般用信號機制就能解決,如果進程間要求傳遞的信息量比較大或者有交換數據的要求,那麼就要使用共享內存和套接字這些通信方式。

名詞解釋:

管道其實是存在於內存中的一種特殊文件,它不屬於文件系統,有自己的數據結構,根據使用範圍還可分爲無名管道和命名管道。

共享內存是通過將共享的內存緩衝區直接附加到進程的虛擬地址空間中來實現的,它是利用內存緩衝區直接交換信息,不需要複製,很快捷、信息量大。

消息隊列緩衝是由系統調用函數來實現消息發送和接收之間的同步,它允許任意進程通過共享消息隊列來實現進程間通信.但是信息的複製需要耗費大量CPU,所以不適用於信息量大或操作頻繁的場合。

●線程同步和線程異步

同步是指一個線程要等待另一個線程執行完之後纔開始執行當前的線程。

異步是指一個線程去執行,它的下一個線程不必等待它執行完就開始執行。

一般一個進程啓動的多個不相干線程,它們之間的相互關係就爲異步,比如遊戲有圖像和背景音樂,圖像是由玩家操作的 而背景音樂是系統循環播放,它們兩個線程之間沒什麼關係各幹各的,這就是線程異步。至於同步的話指的是多線程同時操作一個數據,這個時候需要對數據添加保護,這個保護就是線程的同步

同步使用場景:對於多個線程同時訪問一塊數據的時候,必須使用同步,否則可能會出現不安全的情況,有一種情況不需要同步技術,那就是原子操作,也就是說操作系統在底層保證了操作要麼全部做完,要麼不做。

異步的使用場景:當只有一個線程訪問當前數據的時候。比如觀察者模式,它沒有共享區,主題發生變化後通知觀察者更新,主題繼續做自己的事情,不需要等待觀察者更新完成後再工作。

●多線程同步和互斥有幾種實現方法,分別適用什麼情況

線程同步的話有臨界區,互斥量,信號量,事件。

臨界區適合一個進程內的多線程訪問公共區域或代碼段時使用。

互斥量是可以命名的,也就是說它可以適用不同進程內多線程訪問公共資源時使用。所以在選擇上如果是在進程內部使用的話,用臨界區會帶來速度上的優勢並且能夠減少資源佔用量。

信號量與臨界區和互斥量不同,它是允許多個線程同時訪問公共資源的,它相當於操作系統的PV操作,它會事先設定一個最大線程數,如果線程佔用數達到最大,那麼其它線程就不能再進來,如果有部分線程釋放資源了,那麼其它線程才能進來訪問資源。

事件是通過通知操作的方式來保持線程同步。

注意:互斥量,事件,信號量都是內核對象,可以跨進程使用。

●C++多線程有幾種實現方法

直接使用WIN32 API CreateThread,或者用C運行庫_beginthread創建線程,MFC的話用AfxBeginThread. 還有就是運用第三方線程庫,比如boost的thread等等。

_beginthread和CreateThread的區別:_beginthread內部調用了CreateThread.

如果你的程序只調用 Win32 API/SDK ,就放心用 CreateThread,如果要用到C++運行時庫,那麼就要使用_beginthreadex,因爲C++運行庫有一些函數裏面使用了全局變量,beginthreadex 爲這些全局變量做了處理,使得每個線程都有一份獨立的“全局”量,在這種情況下使用CreateThread的話就會出現不安全的問題

●進程有哪幾種狀態,狀態轉換圖,及導致轉換的事件

 

 

●死鎖

概念:進程間進行通信或相互競爭系統資源而產生的永久阻塞,若無外力作用將永遠處在死鎖狀態。

產生原因:(1)系統資源不足;(2)進程運行推進順序與速度不同也可能導致死鎖;(3)資源分配不當;

產生死鎖四個必要條件:

(1) 互斥條件:就是一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程在請求其它資源而阻塞時,但是它對自己已獲得的資源又保持不放。
(3) 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。
(4) 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關係。

預防死鎖和避免死鎖的方法:在系統設計、進程調度方面注意不讓產生死鎖的四個必要條件成立,確定資源的合理分配算法,避免進程永遠佔用系統資源,對資源分配要進行合理的規劃。

●多線程中棧與堆是公有的還是私有的

因爲線程是共享進程的資源的,所以棧是私有的,堆是公有的。

●線程池的概念

線程池就是一堆已經創建好的線程,最大數目一定,然後初始後都處於空閒狀態,當有新任務進來時就從線程池中取出空閒線程處理任務,任務完成之後又重新放回去,當線程池中的所有線程都在任務時,只能等待有線程結束任務才能繼續執行。

--------------------- 本文來自 zhouchunyue 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/zhouchunyue/article/details/79271869?utm_source=copy

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章