同步和互斥
一、同步和互斥的基本概念
現代操作系統基本都是多任務操作系統,即同時有大量可調度實體在運行,同時運行可能是真的同時運行(SMP架構中),也可能僅僅是操作系統提供的服務(通過將CPU時間分片,并將時間片分給不同的任務)。在多任務操作系統中,同時運行的多個任務可能
這兩種情形是多任務編程中遇到的最基本的問題,也是多任務編程中的核心問題,同步和互斥就是用于解決這兩個問題的。
- 互斥:是指散步在不同任務之間的若干程序片斷,當某個任務運行其中一個程序片段時,其它任務就不能運行它們之中的任一程序片段,只能等到該任務運行完這個程序片段后才可以運行,最基本的場景就是對資源的同時寫,為了保持資源的一致性,往往需要進行互斥訪問。
- 同步:是指散步在不同任務之間的若干程序片斷,它們的運行必須嚴格按照規定的某種先后次序來運行,這種先后次序依賴于要完成的特定的任務,最基本的場景就是任務之間的依賴,比如A任務的運行依賴于B任務產生的數據。
顯然,同步是一種更為復雜的互斥,而互斥是一種特殊的同步。也就是說互斥是兩個任務之 間不可以同時運行,他們會相互排斥,必須等待一個線程運行完畢,另一個才能運行,而同步也是不能同時運行,但他是必須要安照某種次序來運行相應的線程(也 是一種互斥)!因此互斥具有唯一性和排它性,但互斥并不限制任務的運行順序,即任務是無序的。而同步的任務之間則有順序關系。
在實際的設計、編碼中,任務之間的相互依賴也就是情形2是比較容易發現的,而情形1就不那么 明顯了,同步/互斥中出現的問題也多和情形1相關。情形1是和資源訪問相關的,要避免此類問題或者解決已經出現的此類問題首先要解決的問題是識別那類資源 是被多個任務共享的,然后再使用同步/互斥的機制來保護這些資源的訪問。簡單的來說資源大概可以分為以下幾類:
在進行設計、編碼時我們可以首先對任務使用的資源進行分析,看它使用的資源屬于那一類,如果有多個任務需要使用同一類資源,那么這里就需要進行同步/互斥 了。(從這里的分析也可以看出,如果用戶任務不需要使用內核中的資源也不許要使用存儲器中的資源,那么它就不存在情形1所涉及的同步互斥需求)
二、用戶程序編程中常見的多任務
用戶程序編程中常見的多任務有兩種情形: 在這里可以將用戶中的資源進行進一步的分類:
1. 進程中的資源:進程是操作系統分配資源的基本單位,進程的資源主要包括
- 地址空間(涉及到同步互斥的地址段主要是數據段和堆棧段)
- 打開的文件句柄
2. 線程中的資源:一個進程中的所有線程共享進程的地址空間(數據段/堆),打開的文件句柄,由線程獨享的資源包括
- 棧
- 線程專有數據區
三、進程和線程的基本概念
1.進程
進程是程序在計算機上的一次執行活動。當你運行一個程序,你就啟動了一個進程。顯然, 程序是死的(靜態的),進程是活的(動態的)。進程可以分為系統進程和用戶進程。凡是用于完成操作系統的各種功能的進程就是系統進程,它們就是處于運行狀 態下的操作系統本身;其它進程就是用戶進程。進程是操作系統進行資源分配的單位(比如文件句柄,虛擬地址空間等等)。
linux下創建子進程的調用是fork(),它功能就是產生子進程,其特別之處在于它會返回2次。
2.線程
線程是可執行代碼的可分派單元。這個名稱來源于“執行的線索”的概念。在基于線程的多任務的環境中,所有進程有至少一個線程,但是它們可以具有多個任務。這意味著單個程序可以并發執行兩個或者多個任務。
簡而言之,線程就是把一個進程分為很多片,每一片都可以是一個獨立的流程。這已經明顯不同于多進程了,進程是一個拷貝的流程,而線程只是把一條河流截成很 多條小溪。它沒有拷貝這些額外的開銷,但是僅僅是現存的一條河流,就被多線程技術幾乎無開銷地轉成很多條小流程,它的偉大就在于它少之又少的系統開銷。
多線程是為了使得多個線程并行的工作以完成多項任務,以提高系統的效率。
3.使用線程的好處
使用線程的好處有以下幾點:
4.線程唯一的資源
線程唯一的資源包括:
四、進程及線程的比較以及注意事項
線程是多線程編程中的主編程接口。線程僅在進程內部是可見的,進程內部的線程會共享諸如地址 空間、打開的文件等所有進程資源。由于線程可共享進程指令和大多數進程數據,因此一個線程對共享數據進行的更改對進程內其他線程是可見的。一個線程需要與 同一個進程內的其他線程交互時,該線程可以在不涉及操作系統的情況下進行此操作。
進程是操作系統分配資源的單位,不同的進程擁有的資源不同,比如地址空間、打開的文件等等。
1.多線程編程的特殊之處
因為多線程共享進程的大多數數據,因此也引入了新的注意事項:
可重入函數編寫規范:
線程安全與可重入函數之間的關系:
例如標準庫中的malloc是不可重入的,但是標準庫的實現一般都有提供線程安全的版本(具體怎么用線程安全的版本可以查看使用的庫的手冊,總之小心一點)。
線程安全和可重入函數針對的是多線程環境下,由多個線程共享的資源(靜態數據、全局數據)的使用問題。之所以有這個問題是因為在某些函數會使用靜態 或者全局數據,它運行的結果依賴于這些數據,這時如果此類函數在運行中被切換走,然后另一個線程也調用了該函數就會出問題,因此這類問題是特定存在于多線 程環境的(當然類似的問題在進程環境下也存在,存在的原因是信號處理函數可能在任意時刻被調用,因而它可能打斷進程的正常運行;多個進程之間是不存在這類 問題的,因為每個進程看到的都是自己獨立的地址空間)。
2.同步和互斥的實現
- 多線程使用互斥鎖、條件變量、自旋鎖、讀寫鎖和信號量來實現同步和互斥。
- 多進程也使用互斥鎖、條件變量、自旋鎖、讀寫鎖和信號量來實現同步和互斥,但是需要用進程間通信(IPC)來實現信息共享/傳輸。
需要注意的是,并沒有所謂的線程間通信,因為同一個進程內部的線程會共享該進程的資源,比如堆空間、打開的文件等等,因而同一個進程內的多個線程之間不存在通信問題;如果是不同進程之間的線程,就按照進程之間通信方式進行通信即可。
3.何時采用多線程何時采用多進程
這是一個比較艱難的抉擇:),取決于應用場景,它們的區別或許是有參考價值的:
轉載于:https://www.cnblogs.com/xiaozhi123/p/3915987.html
總結
- 上一篇: 专题2-通过按键玩中断\第1课-中断处理
- 下一篇: 禅道下载包地址