1. 程式人生 > >作業系統原理讀書筆記之程序同步

作業系統原理讀書筆記之程序同步

程序同步(synchronization):指系統中多個程序中發生的事件存在某種時序關係,需要相互合作,共同完成一項任務。形象的說。一個程序執行到某一點時,要求另一夥伴程序為它提供訊息,在未獲得訊息之前,該程序進入阻塞態,獲得訊息後被喚醒進入就緒態。

程序同步機制

一、訊號量及PV操作

訊號量是一個特殊變數,用於程序間傳遞資訊,通常是一個整數值,由Dijkstra提出,最初用於解決互斥問題,訊號量只有兩個(0,1),稱作二元訊號量; 後來推廣到多值,用於解決同步問題。注意訊號量是一個靜態的值,多個程序可以共享這個記憶體單元 這裡我們舉例定義一個訊號量的結構體(也可以定義為一個單一整型)定義如下:
struct semaphore{
    int count;
    queueType queue;
}s;
其中count用於傳遞資訊,程序可以掛到佇列queue上 對訊號量可以實施的操作只有三個:1、初始化;2、P操作;3、V操作(P、V分別是荷蘭語proberen(test)和verhogen(increment)) P操作:
P(s){
    s.count--;
    if(s.count < 0){
        //將呼叫P操作的程序狀態置為阻塞態,並插入相應等待佇列s.queue末尾;
        //重新排程
    }
}

V操作:
V(s){
    s.count++;
    if(s.count <= 0){
        //喚醒s.queue中等待的一個程序,改變其狀態為就緒態,並將其插入就緒佇列
        //並不會立即切換到被喚醒的程序,而是呼叫V操作的程序繼續執行
    }
}

用PV操作解決程序間互斥問題

對同一個訊號量的PV操作在相同的程式碼塊,即可解決互斥問題
  • 劃定臨界區
  • 設定訊號量count初值為1
  • 在臨界區前實施P(s)
  • 在臨界區之後實施V(s)
s.count = 1;
P(s.count);
//臨界區
V(s.count)

用PV操作解決同步問題(生產者消費者問題)

如果對同一個訊號量的PV操作分部在不同的程式碼塊中,就很巧妙的解決了同步問題
void producer(void){
    int item;
    while(TRUE){
        item = produce_item();
        P(&empty);
        P(&mutex);//解決互斥
        insert_item(item);
        V(&mutex);
        V(&full);
    }
}
void consumer(void){
    int item;
    while(TRUE){
        P(&full);
        P(&mutex);
        item = remove_item();
        V(&mutex);
        V(&empty);
        consume_item(item);
    }
}

其中empty是空緩衝區的個數,也就是可以生產多少item,初值為N; full表示滿緩衝區的個數,即可消費的item有多少,初值為0; mutex初值為1,用於解決互斥問題; 可以看到,對empty和full的操作分佈在不同的函式中,在producer中,如果空緩衝區個數滿了,則進入阻塞態,等待消費者消費,同理consumer,一開始full為0,則阻塞等待生產者生產,當生產者生產item之後會進行V(&full)操作喚醒消費者被阻塞的程序 思考: 1、這兩個函式中的兩個P操作是否可以顛倒 如果消費者程序先執行,會將mutex上鎖,且自身由於無item可消費,進入阻塞態;而生產者由於mutex互斥,無法將item放入緩衝區,這樣就造成了死鎖 2、兩個V操作是否可以顛倒 由於V操作不會使得呼叫V操作的程序進入阻塞態,因此是可以的,但是斥在設計的原則應將臨界區範圍縮到最小,這樣不會影響生產和消費的效率

二、管程

由於PV操作在界定臨界區及解決互斥問題容易出錯,編寫程式較困難,因此出現了管程這種更完善的同步機制 管程是由共享資源資料結構及在其上操作的一組過程(方法、函式)組成 程序和管程的關係: 程序只能通過呼叫管程中的過程來間接訪問管程中的資料結構 管程是互斥進入的,其互斥性是由編譯器負責保證; 同步的解決方案是在管程中設定條件變數及wait/signal操作。這裡需要注意,如果一個程序或執行緒在條件變數上等待,應該先釋放管程的使用權,使其他執行緒或程序可以操作管程

管程的種類

當一個執行緒進入管程並執行喚醒操作(A喚醒B),這時管程中就存在兩個同時處於活動狀態的程序,A和B執行的先後順序不同,導致管程的種類不同
  1. A等待,B執行,例如Hoare管程
  2. A繼續執行,B等待,典型有MESA管程
  3. 喚醒操作為管程中最後一個可執行操作,意思就是A在喚醒B之後立刻出管程,B在管程內繼續執行,採用這種策略的有Hansen管程

Hoare管程


  • 管程入口處設定一個程序等待佇列,因為管程是互斥進入的,因此設定一個入口等待佇列讓試圖進入已被佔用的管程的程序等在佇列中
  • 如果一個程序不滿足條件,則進入阻塞態,等在條件變數上,每個條件變數都有獨立的佇列
  • 如果程序A喚醒程序B,則A等待,B執行,而A等待在緊急等待佇列中,緊急等待佇列的優先順序高於入口等待佇列
條件變數是在管程內部使用的一種特殊型別的變數(靜態),假設定義為c,條件變數的等待佇列為cqueue 對於c,可以執行wait(c)和signal(c)操作 wait(c):如果緊急等待佇列為非空,喚醒第一個等待者;否則釋放管程互斥權,入口等待佇列隊首的程序進入管程,執行此操作的程序進入cqueue的隊尾 signal(c):如果cqueue為空,則相當於空操作,執行此操作的程序繼續執行;否則喚醒第一個等待者,執行此操作的程序進入緊急等待佇列的末尾

Hoare管程的缺點

由於Hoare管程在A喚醒B後立刻執行B,此時A的時間片並沒有用完,導致增加了許多上下文切換的操作,為了避免這種弊端,MESA管程應運而出

MESA管程

MESA管程的沒有signal操作,而被稱作notify,更形象 notify操作通知一個等在cqueue上的程序被轉移到緊急等待佇列中,假如A程序執行notify(c),使得B程序進入緊急等待佇列,當A被切換下cpu時,不能保證立刻將B切換執行,中間有可能有多個程序影響條件變數c,因此在B程序執行前還需要檢查條件變數是否成立 優化:
  1. 可以在執行notify操作時,關聯一個動作,這個動作將條件變數上等待了一定時間的程序無論是否被notify都切換為就緒態,避免個別程序由於等待無限期推遲而處於飢餓狀態
  2. notify改進為notifyAll

管程的應用

我們用管程解決生產者和消費者問題(這裡只給出了生產insert的操作,採用Hoare管程)
class Monitor{
    static final int N = 100;
    private int buffer[] = new int[N];
    private int count = 0, hi = 0;
    
    /**
     * 用synchronized解決互斥
     */
    public synchronized void insert(int item) {
        if(count == N)
            go_to_sleep();
        
        buffer[hi] = item;
        hi = (hi+1) % N;//update hi
        count += 1;
        if(count == 1)
            notify();
    }
}

如果採用MESA管程,要將 if(count == N)改為 while(count == N) 因為MESA管程需要不斷檢查條件變數,並不是直接可以執行

相關推薦

作業系統原理讀書筆記程序同步

程序同步(synchronization):指系統中多個程序中發生的事件存在某種時序關係,需要相互合作,共同完成一項任務。形象的說。一個程序執行到某一點時,要求另一夥伴程序為它提供訊息,在未獲得訊息之前,該程序進入阻塞態,獲得訊息後被喚醒進入就緒態。 程序同步機制 一、

作業系統原理讀書筆記程序互斥

臨界資源:表示該資源一次只允許一個程序使用,也叫互斥資源或共享變數 臨界區(互斥區):各個程序對某個臨界資源實施操作的程式片段 解決程序互斥的方法 軟體方案: 1、加鎖(對free加鎖) ... /

作業系統原理讀書筆記虛擬儲存技術

虛擬儲存技術 是指:當程序執行時,先將其中一部分裝入記憶體,另一部分暫留在磁碟,當要執行的指令或訪問的資料不在記憶體時,由作業系統自動完成將他們從磁碟調入記憶體的工作 虛存與儲存體系的關係 虛存構建在儲存體系之上,把記憶體和磁碟有機的結合起來使用,從而得到一個容量很大的記

作業系統原理讀書筆記檔案系統

磁碟空間管理 有三種管理方式,對應三種資料結構 點陣圖,每一位對應一個物理塊,未使用上0,被使用是1,分配的時候需要遍歷點陣圖找到不為1的位然後分配空閒塊表,將所有空閒塊記錄在一個表中,每個表項紀錄起始塊號和空閒的塊數,有點類似於記憶體空間管理策略裡的不等長劃分。這種方式

讀書筆記面向對象的程序設計-1理解對象

-i chrom conf 理解 cnblogs object ftw 不能 pro ECMA-262把對象定義為:“無序屬性的集合,其屬性可以包含基本值、對象或者函數。” 創建自定義對象的最簡單方式就是創建一個Object的實例 eg:先創建一個名為person的對象,

第四周讀書筆記——《程序員修煉道——從小工到專家》

本周 post align 課程 tex 如何實現 知識 我想 分享 本周我讀的書是美國Andrew Hunt與David Thomas所著的《程序員修煉之道——從小工到專家》。翻開第一頁,我就可以看到無數來自其他專業人士對這本書的褒獎。俗話說,贊美總是不嫌多,我大概瀏覽了

讀書筆記ZLBOG如何選擇ASP和PHP程序以及數據庫版本?

SQLSERVER2012 數據庫 ZBLOG PHP 最近一直在研究和解決ZBLOG數據庫的事情,因為早期的博客一般都采用小型數據庫,但時至今日,數據了逐漸增大,ACCESS這樣的微軟桌面級數據庫已經不能夠處理當前的數據量了,就算是建立個博客,數據超過2萬條也壓力山大,生成一次數據要很長時間

從Paxos到Zookeeper分散式一致性原理與實踐 讀書筆記(一) 分散式架構

1.1 從集中式到分散式  1 集中式特點  結構簡單,無需考慮對多個節點的部署和節點之間的協作。  2  分散式特點 分不性:在時間可空間上隨意分佈,機器的分佈情況隨時變動 對等性:計算機之間沒有主從之分,所有計算機之間是對等的。副本是分散式系統對資料

作業系統程序同步問題

程序同步的兩種形式的制約關係 間接相互制約關係(程序互斥) 程序-程序 直接相互制約關係(程序同步) 程序-資源-程序 此處的資源一般指(臨界資源:在一段時間內只允許一個程序訪問的資源。臨界資源的訪問要求互斥的訪問。) 講到程序同步就不得不提生產者-消費者問題了, int in=0,ou

讀書筆記《Linux作業系統奧祕》

Linux作業系統之奧祕 邱世華 著 電子工業出版社   市面上大部分關於Linux的書都著重探討Server管理,X Window操作上,缺乏Linux根基;也有些書以對Kernel的解析為主,把Linux的應用切除在外。本書試圖在這兩個極端之間

《現代作業系統讀書筆記程序和執行緒

一、程序和執行緒 什麼是程序 程序是程式執行的一個過程,程式指的是我們通常意義上的程式碼,一個程式可以被執行多次,也就產生了多個程序。程序是作業系統資源分配和排程的基本單位,是作業系統結構的基礎。每個程序都有屬於自己的地址空間。 作業系統中的程序一般由三部分組

《金子塔原理讀書筆記解決問題的邏輯

界定問題 判斷問題的是否存在,通常要看經過努力得到的結果(現狀),與希望得到的結果(目標)之間是否有差距。由某一特定背景導致的某一特定結果,稱為非期望結果(R1,即現狀,Undesired Result) 問題是指你不喜歡某一結果(比如銷售額降低),想得到其他結果(比

計算機作業系統讀書筆記___程序狀態的討論

推薦閱讀程序的引入。馬克思指出原因與結果是唯物辯證法的一對基本範疇。  為什麼會有這些狀態而不是其他狀態?換句話說,作業系統設計者提出這些狀態的用意是什麼?一句話:把CPU(處理機資源)的每一滴潛能都壓榨乾淨。I/O裝置可以閒置,記憶體在系統中程序比較少的時候也會閒置

Javascript高級程序設計--讀書筆記面向對象(一)

friend 自定義 包括 類型 有一個 問題 相同 elb 模式 哈哈哈萬物皆對象,終於到了js的面向對象篇。 一、屬性類型 (1)數據屬性 數據屬性包含一個數據值的位置,在這個位置可以寫入和讀取數值,數據屬性有四個描述器行為的特性 [[Configurable]]:表

作業系統學習筆記程序同步

互相協作的程序之間有共享的資料,於是這裡就有一個併發情況下,如何確保有序操作這些資料、維護一致性的問題,即程序同步。從底層到高階應用,同步機制依次有臨界區、訊號量、管程、原子事務。1、臨界區每個程序有一個程式碼段稱為臨界區,共享資料在此進行操作。沒有兩個程序同時在臨界區執行。

讀書筆記《Windows核心原理與實現》

原文地址 近學習《Windows核心原理與實現》發現其博大精深,粗略過了一遍,很多東西比較茫然,看書之餘把書中涉及的函式,結構,全域性變數的所在頁數總結出來,便於以後查閱。 由於半自動半手工,難免有寫錯的地方,如有發現還請留言通知,謝謝。 函式 函式名稱 所在頁

讀書筆記應用程式與作業系統之間的關係——《作業系統真相還原》

這個知識點很好的解釋了為什麼一些程式不能跨平臺使用,比如windows與linux之間的應用程式一般不能通用,底層庫不同,可執行程式的格式也不同,後面章節中作者也點明瞭這個問題。此問題可見知乎上的討論:主要的原因是格式不同和API不同,前者更重要一些。http://www.

《大型網站技術架構核心原理與案例分析》讀書筆記RAID技術

        RAID(廉價磁碟冗餘陣列)技術主要是為了改善磁碟的訪問延遲,增強磁碟的可用性和容錯能力。目前伺服器級別的計算機都支援插入多塊磁碟(8塊或者更多),通過使用RAID技術,實現資料在多塊磁碟上的併發讀寫和資料備份。        假設伺服器有N塊磁碟。     

Javascript高級程序設計--讀書筆記面向對象(二)

原型鏈 func pro 原型對象 ets span gre {} javascrip 前面講了面向對象的封裝,這章我們就來說一說繼承 1.原型鏈 實現原型鏈有一種基本模式,其代碼大概如下 <script> function Super

《大型網站技術架構》讀書筆記六:永無止境網站的伸縮性架構

映射 應對 方法 訂閱 知識 位置 n+1 轉換 bsp 此篇已收錄至《大型網站技術架構》讀書筆記系列目錄貼,點擊訪問該目錄可獲取更多內容。 首先,所謂網站的伸縮性,指不需要改變網站的軟硬件設計,僅僅通過改變部署的服務器數量就可以擴大或者縮小網站的服務處理能力。在整個互聯