操作系统(三)
學習記錄(3)
線程
1.線程的優勢在哪?
1.1 多線程之間會共享同一塊地址空間和所有可用數據的能力,這是進程所不具備的。
1.2 線程要比進程更輕量級,由于線程更輕,所以它比進程更容易創建,也更容易撤銷。在許多系統中,創建一個線程要比創建一個進程快10 -100倍。
1.3 第三個原因可能是性能方面的探討,如果多個線程都是CPU密集型的,那么并不能獲得性能上的增強,但是如果存在著大量的計算和大量的VO處理,擁有多個線程能在這些活動中彼此重疊進行,從而會加快應用程序的執行速度。
多線程解決方案:
?
每次服務器從某個請求工作的狀態切換到另一個狀態時,都必須顯示的保存或者重新裝入相應的計算狀態。這里,每個計算都有一個被保存的狀態,存在一個會發生且使得相關狀態發生改變的事件集合,我們把這類設計稱為有限狀態機(finite-state machine)。
2 經典的線程模型是什么樣的,有什么特點?
下圖中,我們可以看到有一個進程三個線程的情況。每個線程都在相同的地址空間中運行。
2.1線程的屬性.
線程不像是進程那樣具備較強的獨立性。同一個進程中的所有線程都會有完全一樣的地址空間,這意味著它們也共享同樣的全局變量。由于每個線程都可以訪問進程地址空間內每個內存地址,因此一個線程可以讀取、寫入甚至擦除另一個線程的堆棧。線程之間除了共享同一內存空間外,還具有如下不同的內容
上圖左邊的是同一個進程中每個線程共享的內容,上圖右邊是每個線程中的內容。也就是說左邊的列表是進程的屬性,右邊的列表是線程的屬性。
2.2 線程的系統調用
進程通常會從當前的某個單線程開始,然后這個線程通過調用一個庫函數(比如thread_create )創建新的線程。線程創建的函數會要求指定新創建線程的名稱。創建的線程通常都返回一個線程標識符,該標識符就是新線程的名字。當一個線程完成工作后,可以通過調用一個函數(比如thread_exit)來退出。緊接著線程消失,狀態變為終止,不能再進行調度。在某些線程的運行過程中,可以通過調用函數例如thread_join ,表示一個線程可以等待另一個線程退出。這個過程阻塞調用線程直到等待特定的線程退出。在這種情況下,線程的創建和終止非常類似于進程的創建和終止。另一個常見的線程是調用thread_yield ,它允許線程自動放棄CPU從而讓另一個線程運行。這樣一個調用還是很重要的,因為不同于進程,線程是無法利用時鐘中斷強制讓線程讓出CPU的。
POSIX 線程
POSIX線程(通常稱為pthreads)是一種獨立于語言而存在的執行模型,以及并行執行模型。它允許程序控制時間上重疊的多個不同的工作流程。每個工作流程都稱為一個線程,可以通過調用POSIX Threads API來實現對這些流程的創建和控制。可以把它理解為線程的標準。
POSIX Threads的實現在許多類似且符合POSIX的操作系統上可用,例如 FreeBSD、NetBSD、OpenBSD、Linux、macOS、Android、Solaris,它在現有 Windows APl之上實現了pthread
所有的Pthreads 都有特定的屬性,每一個都含有標識符、一組寄存器(包括程序計數器)和一組存儲在結構中的屬性。這個屬性包括堆棧大小、調度參數以及其他線程需要的項目。
新的線程會通過pthread_create創建,新創建的線程的標識符會作為函數值返回。這個調用非常像是UNIX中的 fork系統調用(除了參數之外),其中線程標識符起著PID的作用,這么做的目的是為了和其他線程進行區分。當線程完成指派給他的工作后,會通過pthread_exit來終止。這個調用會停止線程并釋放堆棧。
一般一個線程在繼續運行前需要等待另一個線程完成它的工作并退出。可以通過pthread_join 線程調用來等待別的特定線程的終止。而要等待線程的線程標識符作為一個參數給出。
有時會出現這種情況:一個線程邏輯上沒有阻塞,但感覺上它已經運行了足夠長的時間并且希望給另外一個線程機會去運行。這時候可以通過pthread_yield 來完成。下面兩個線程調用是處理屬性的。pthread_attr_init建立關聯一個線程的屬性結構并初始化成默認值,這些值(例如優先級)可以通過修改屬性結構的值來改變。
?
?
?
?
?
?
?
總結
- 上一篇: 【C++】【十二】排序实现及思路
- 下一篇: OpenCV 【十一】—— 图像去畸变,