日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

同步和互斥

發布時間:2023/12/9 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 同步和互斥 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、同步和互斥的基本概念

現代操作系統基本都是多任務操作系統,即同時有大量可調度實體在運行,同時運行可能是真的同時運行(SMP架構中),也可能僅僅是操作系統提供的服務(通過將CPU時間分片,并將時間片分給不同的任務)。在多任務操作系統中,同時運行的多個任務可能

  • 都需要訪問/使用同一種資源
  • 多個任務之間有依賴關系,某個任務的運行依賴于另一個任務
  • 這兩種情形是多任務編程中遇到的最基本的問題,也是多任務編程中的核心問題,同步和互斥就是用于解決這兩個問題的。

    • 互斥:是指散步在不同任務之間的若干程序片斷,當某個任務運行其中一個程序片段時,其它任務就不能運行它們之中的任一程序片段,只能等到該任務運行完這個程序片段后才可以運行,最基本的場景就是對資源的同時寫,為了保持資源的一致性,往往需要進行互斥訪問。
    • 同步:是指散步在不同任務之間的若干程序片斷,它們的運行必須嚴格按照規定的某種先后次序來運行,這種先后次序依賴于要完成的特定的任務,最基本的場景就是任務之間的依賴,比如A任務的運行依賴于B任務產生的數據。

    顯然,同步是一種更為復雜的互斥,而互斥是一種特殊的同步。也就是說互斥是兩個任務之 間不可以同時運行,他們會相互排斥,必須等待一個線程運行完畢,另一個才能運行,而同步也是不能同時運行,但他是必須要安照某種次序來運行相應的線程(也 是一種互斥)!因此互斥具有唯一性和排它性,但互斥并不限制任務的運行順序,即任務是無序的。而同步的任務之間則有順序關系。


    在實際的設計、編碼中,任務之間的相互依賴也就是情形2是比較容易發現的,而情形1就不那么 明顯了,同步/互斥中出現的問題也多和情形1相關。情形1是和資源訪問相關的,要避免此類問題或者解決已經出現的此類問題首先要解決的問題是識別那類資源 是被多個任務共享的,然后再使用同步/互斥的機制來保護這些資源的訪問。簡單的來說資源大概可以分為以下幾類:

  • 存儲在存儲器中的資源:這類資源不依賴于任務的運行,多以文件或數據庫的形式存在于存儲器中,它們對所有任務都是可見的(不考慮權限問題)。
  • 內核中的資源:此類資源由內核創建和維護,對內核中的任務和獲取了該資源的句柄的用戶任務可見(對于內核創建的資源,如果用戶任務想要使用它,往往都需要通過某種API類獲取資源的句柄)。
  • 用戶任務中的資源:此類資源僅在該任務內可見,其它任務是無法訪問該類資源的。
  • 在進行設計、編碼時我們可以首先對任務使用的資源進行分析,看它使用的資源屬于那一類,如果有多個任務需要使用同一類資源,那么這里就需要進行同步/互斥 了。(從這里的分析也可以看出,如果用戶任務不需要使用內核中的資源也不許要使用存儲器中的資源,那么它就不存在情形1所涉及的同步互斥需求)

    二、用戶程序編程中常見的多任務

    用戶程序編程中常見的多任務有兩種情形:
  • 多進程
  • 多線程
  • 在這里可以將用戶中的資源進行進一步的分類:
    1. 進程中的資源:進程是操作系統分配資源的基本單位,進程的資源主要包括

    • 地址空間(涉及到同步互斥的地址段主要是數據段和堆棧段)
    • 打開的文件句柄

    2. 線程中的資源:一個進程中的所有線程共享進程的地址空間(數據段/堆),打開的文件句柄,由線程獨享的資源包括

    • 線程專有數據區

    三、進程和線程的基本概念

    1.進程

    進程是程序在計算機上的一次執行活動。當你運行一個程序,你就啟動了一個進程。顯然, 程序是死的(靜態的),進程是活的(動態的)。進程可以分為系統進程和用戶進程。凡是用于完成操作系統的各種功能的進程就是系統進程,它們就是處于運行狀 態下的操作系統本身;其它進程就是用戶進程。進程是操作系統進行資源分配的單位(比如文件句柄,虛擬地址空間等等)。

    linux下創建子進程的調用是fork(),它功能就是產生子進程,其特別之處在于它會返回2次。

    2.線程

    線程是可執行代碼的可分派單元。這個名稱來源于“執行的線索”的概念。在基于線程的多任務的環境中,所有進程有至少一個線程,但是它們可以具有多個任務。這意味著單個程序可以并發執行兩個或者多個任務。
    簡而言之,線程就是把一個進程分為很多片,每一片都可以是一個獨立的流程。這已經明顯不同于多進程了,進程是一個拷貝的流程,而線程只是把一條河流截成很 多條小溪。它沒有拷貝這些額外的開銷,但是僅僅是現存的一條河流,就被多線程技術幾乎無開銷地轉成很多條小流程,它的偉大就在于它少之又少的系統開銷。
    多線程是為了使得多個線程并行的工作以完成多項任務,以提高系統的效率。

    3.使用線程的好處

    使用線程的好處有以下幾點:

  • .提高應用程序的響應:可以對任何一個包含許多相互獨立的活動的程序進行重新設計,以便將每個活動定義為一個線程。例如,多線程 GUI 的用戶不必等待一個活動完成即可啟動另一個活動。
  • 更有效地使用多處理器:通常,要求并發線程的應用程序無需考慮可用處理器的數量。使用額外的處理器可以明顯提高應用程序的性能。具有高度并行性的數值算法和數值應用程序(如矩陣乘法)在多處理器上通過多個線程實現時,運行速度會快得多。
  • 改進程序結構:許多應用程序都以更有效的方式構造為多個獨立或半獨立的執行單元,而非整塊的單個線程。多線程程序比單線程程序更能適應用戶需求的變化。
  • 占用較少的系統資源:多進程與多線程相比,每個進程都有一個完整的地址空間和操作環境狀態。每個進程用于創建和維護大量狀態信息的成本,與一個線程相比,無論是在時間上還是空間上代價都更高。此外,進程間所固有的獨立性使得程序員需要花費很多精力來處理不同進程間的通信。
  • 4.線程唯一的資源

    線程唯一的資源包括:

  • 線程 ID
  • 寄存器狀態(包括 PC 和棧指針)
  • 信號掩碼
  • 優先級
  • 線程專用存儲
  • 四、進程及線程的比較以及注意事項

    線程是多線程編程中的主編程接口。線程僅在進程內部是可見的,進程內部的線程會共享諸如地址 空間、打開的文件等所有進程資源。由于線程可共享進程指令和大多數進程數據,因此一個線程對共享數據進行的更改對進程內其他線程是可見的。一個線程需要與 同一個進程內的其他線程交互時,該線程可以在不涉及操作系統的情況下進行此操作。
    進程是操作系統分配資源的單位,不同的進程擁有的資源不同,比如地址空間、打開的文件等等。

    1.多線程編程的特殊之處

    因為多線程共享進程的大多數數據,因此也引入了新的注意事項:

  • 線程安全函數:在C語言中局部變量是在棧中分配的,任何未使用靜態數據或全局數據的函數都是線程安全的。非線程安全的函數可以通過加鎖的方式來使函數實現線程安全。
  • 線程安全的(Thread-Safe):如果一個函數在同一時刻可以被多個線程安全地調用,就稱該函數是線程安全的。線程安全函數解決多個線程調用函數時訪問共享資源的沖突問題。
  • 可重入(Reentrant):函數可以由多于一個線程并發使用,而不必擔心數據錯誤。可重入函數可以在任意時刻被中斷,稍后再繼續運行,不會丟失數據。可重入性解決函數運行結果的確定性和可重復性。
  • 可重入函數編寫規范:

  • 不在函數內部使用靜態或全局數據
  • 不返回靜態或全局數據,所有數據都由函數的調用者提供。
  • 使用本地數據,或者通過制作全局數據的本地拷貝來保護全局數據。
  • 如果必須訪問全局變量,利用互斥機制來保護全局變量。
  • 不調用不可重入函數。
  • 線程安全與可重入函數之間的關系:

  • 一個函數對于多個線程是可重入的,則這個函數是線程安全的。
  • 一個函數是線程安全的,但并不一定是可重入的。【例如可以使用互斥鎖實現的線程安全】
  • 可重入性要強于線程安全性。
  • 例如標準庫中的malloc是不可重入的,但是標準庫的實現一般都有提供線程安全的版本(具體怎么用線程安全的版本可以查看使用的庫的手冊,總之小心一點)。

    線程安全和可重入函數針對的是多線程環境下,由多個線程共享的資源(靜態數據、全局數據)的使用問題。之所以有這個問題是因為在某些函數會使用靜態 或者全局數據,它運行的結果依賴于這些數據,這時如果此類函數在運行中被切換走,然后另一個線程也調用了該函數就會出問題,因此這類問題是特定存在于多線 程環境的(當然類似的問題在進程環境下也存在,存在的原因是信號處理函數可能在任意時刻被調用,因而它可能打斷進程的正常運行;多個進程之間是不存在這類 問題的,因為每個進程看到的都是自己獨立的地址空間)。

    2.同步和互斥的實現

    • 多線程使用互斥鎖、條件變量、自旋鎖、讀寫鎖和信號量來實現同步和互斥。
    • 多進程也使用互斥鎖、條件變量、自旋鎖、讀寫鎖和信號量來實現同步和互斥,但是需要用進程間通信(IPC)來實現信息共享/傳輸。

    需要注意的是,并沒有所謂的線程間通信,因為同一個進程內部的線程會共享該進程的資源,比如堆空間、打開的文件等等,因而同一個進程內的多個線程之間不存在通信問題;如果是不同進程之間的線程,就按照進程之間通信方式進行通信即可。

    3.何時采用多線程何時采用多進程

    這是一個比較艱難的抉擇:),取決于應用場景,它們的區別或許是有參考價值的:

  • 一個進程中的所有線程都必須運行相同的可執行程序(它們最多能做到的是運行相同可執行程序的不同部分)。而一個子進程可以運行一個完全不同的可執行程序。
  • 進程是操作系統分配資源的基本單位,而線程則不是,線程獨立擁有的主要是棧和線程專用緩沖區
  • 由于同一個進程內的多個線程共享同一塊虛擬內存和其它資源,因而一個線程出錯可能會影響到同一個進程中的其它線程。而多進程環境下,一個進程出錯并不會影響其它進程,因為每一個進程都擁有自己獨立的資源。
  • 創建新進程時的資源拷貝使得創建新的進程比創建新的線程效率底下很多。不過由于寫時拷貝機制的存在,因而如果子進程不產生寫請求,這個影響就會很小。
  • 如果一個任務可以被分解為多個幾乎完全相同的子任務,則多線程就可能是一個很好的選擇。
  • 由于同一個進程內的多個線程共享進程的資源,因而多個線程共享資源非常簡單(當然,代價是必須防止出現競態)。而多進程之間共享資源則需要通過IPC機制
  • 轉載于:https://www.cnblogs.com/xiaozhi123/p/3915987.html

    總結

    以上是生活随笔為你收集整理的同步和互斥的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。