天天看點

作業系統(十四)------程序間通信的幾種方式

下面我們介紹程序間通信機制。有了信号量有了管程之後,為什麼程序之間還需要新的通信機制?這主要原因是,信号量和管程隻能傳遞很簡單的資訊,不能傳遞大量的資訊 比如說,我要把一個大的數組傳送給另外一個程序,那麼信号量和管程在這一方面是做不到的。另外呢管程不适合于用于多處理器的情況 是以呢,我們需要在傳遞大量資訊的時候呢,引入新的通信機制,那麼這個通信機制呢我們稱之為,程序間通信機制其中一個非常典型的形式呢,就是消息傳遞消息傳遞呢,實際上就是由一個 send和receive 這樣的,提供這樣的原語操作 那麼,當一個程序要把息,消息發送給另外一個程序的時候呢,就去調用 send 當另外一個程序說,我要想接收消息的時候呢,就去調用 receive 操作那麼,程序通信機制呢,它适合的場景很多比如說,基于網絡的分布式系統比如說,基于共享記憶體的多處理機系統。當然啦,它也适合于用于單處理機系統是以,它适合的場景非常多。那麼它的用途也很廣,可以解決程序之間的同步問題、互斥問題也可以解決啊程序的通信問題,傳遞大量資訊的問題,是以它的用途也很廣是以呢,程序間通信機制是非常重要的啊一項内容通常呢,我們有這樣幾個典型的通信方式一個是消息傳遞,一個是共享記憶體一個是管道,還有套接字和遠端過程調用 那麼,像套接字、遠端過程調用都适合于用于網絡或者是分布式系統那我們首先介紹一下消息傳遞消息傳遞,我們先看一下這個場景有一個程序它要發送消息給另外一個程序是以,這個程序我們稱之為發送程序,這個叫接收程序發送程序把消息準備好啦,我們可以看到消息準備好啦,消息的内容和消息的大小但是由于發送程序它所在自己的位址空間它不能夠到接收程序位址空間進行任何操作是以,這個事情,發送消息這個事情,必須由作業系統幫助它來完成 那麼作業系統呢,在它的區域裡頭設定了一個一組啊,消息緩沖區那麼,每一個消息都由一個 buffer 來 接收這個消息啊,存放這個消息。 而 buffer的資料 結構呢,是這樣一個結構。 它包括了消息的頭兒,啊這樣一些個資料結構,描述了消息的類型,接收程序的 ID 還有發送程序的 ID ,以及消息的長度和一些控制資訊然後就是消息的内容啊,把所有消息内容都可以放在一個 buffer 裡頭,這是一個等長的啊消息 那麼,當發送程序 想要把消息發送到 這個這個另外一個程序的時候,那麼它要調用這個發送原語 send 而發送原語呢實際上呢,它是一個陷入了作業系統,由作業系統完成的一個發送的過程是以呢,陷入核心,然後作業系統呢接收過來那麼,作業系統主要做的工作就是把發送程序準備好的消息拷貝到某一個緩沖區裡頭找一個空的緩沖區,把消息内容拷貝過去然後,把這個消息挂接到接收程序的消息隊列的末尾。大家還記不記得在這個講程序控制塊的時候那麼PCB裡頭,有很多的啊資料項,那麼其中包括了一個資料項就是,消息隊列的指針 那麼,通過這個指針,所有發給這個程序的消息,都挂接到這個隊列裡頭做完這些事情之後,那麼發送程序其實就是完成了發送工作,可以接着啊做下面的事情了那麼什麼時候接收程序上 CPU了 執行到了receive 這樣一個接收原語呢 那麼,可能它被排程上 CPU之後,它來執行這個原語 當這個時候,執行這個原語,也是陷入作業系統核心 那麼由作業系統來完成相應的工作,是以作業系統來幫助它把這個消息複制到了,接收程序的位址空間 那麼,這樣就完成了一個發送的過程,一個接收的過程是以,發送程序隻是把消息準備好調用 send 操作,那麼作業系統 做相應的複制消息的内容,挂接的内容 那麼,接收消息呢,接收程序呢接收消息的時候呢,也是把這個 請求送出給作業系統,作業系統完成把消息複制到接收程序空間的工作是以呢,作業系統要提供這樣一個通信機制,來完成程序之間的資訊傳送這裡頭我們簡單給出來,用 P、V操作來實作SEND原語 那麼,應該首先先要得到一個空的緩沖區,是以通過一個 P操作,看看有沒有空緩沖區了 因為,我們假設空緩沖區的個數是有限的 然後,就去摘取空緩沖區 下面是,把消息複制到緩沖區裡頭 接着,把消息啊挂接到接收程序的消息隊列然後,通知接收程序說,有消息了。那麼如果接收程序剛才來取消息,沒有取到。那麼進入等待,這個時候呢這樣一個操作就會把這個接收程序喚醒重新讓它就緒。 那麼如果,接收程序還沒有執行到 receive的話呢,那麼這就是通知是吧,啊增加了一個新的消息 那麼接收程序執行receive的時候,就有消息可接收了 關于receive的原語怎麼實作? 大家回去可以按照這樣一個啊模式來試着 實作一下。 下面我們來介紹第二種的啊,程序間通信的方式叫做,共享記憶體我們來看一下啊,這是啊兩個程序分别有自己的位址空間,那麼它們兩個程序之間如果需要送一些資料給對方,或者是讀一些資料,那怎麼做呢?那麼可以通過共享記憶體的方式。那麼用這種方式來實作這個消息傳遞,啊消息的這個通信,那麼需要解決兩個問題第一個問題呢,需要在實體記憶體裡頭建立一個大家能夠共享的一塊記憶體空間并且,通過相應的映射,把這個實體記憶體空間 映射到了兩個程序的 相應的位址空間裡頭。 我們可以看到在程序 1 的這一塊空間 和程序 2的這一塊空間,都映射到了同一塊實體記憶體 通過這樣一個映射,那麼這兩個程序其實都是在這塊實體記憶體上做相應的操作 是以這是第一個問題。 第二個問題呢,其實就是我們前面介紹的 讀者、寫者問題,因為,這塊區域不能同時去寫 但是呢,可以同時去讀。是以呢,我們可以利用控制讀者、寫者問題的這個方法呢來解決啊它們之間的這個互斥問題那麼,資料當程序 1要想往這個實體記憶體裡頭讀或者寫資料的時候呢 那麼,它實際上是往它的那塊空間裡頭去寫 而這個空間呢,因為映射到了這塊實體記憶體,相當于往這裡去寫 那程序2也是一樣,假設它是從這裡去讀資料 讀呢,讀到了自己的這個空間。 其實呢這個空間内容呢也就是讀到了 這個程序的相應的,當做讀操作的時候呢,它倆是關聯起來的 這就是共享記憶體 第三種程序間通信方式呢,就是管道通信方式 管道通信方式呢,其實非常形象,是利用了一個傳輸的媒體,它是一個放了很多資料的一個緩沖的傳輸媒體 然後,這個傳輸媒體呢可以是記憶體的一塊空間,也可以是某一個檔案用這樣一個媒體聯接了兩個不同的程序,這兩個程序可以通過這個中間這個傳輸媒體來互相通信假設這像一個管道一樣,那麼,發送程序實際上就是往管道裡寫啊可以有很多發送程序都往管道裡寫 那麼,接收程序呢,實際上就是從管道讀,啊管道讀讀完了,這些内容就沒了。是以寫是在尾巴上寫,那麼讀呢是在頭上讀。 這就是一個管道通信方式一個示意。在實作管道通信的方式的過程中呢,我們可以看到有幾個問題。第一個問題呢,是字元流的方式來寫入讀出。 這它是沒有格式的,是按字元流的方式寫入讀出。而且是有順序的,先寫的先讀出。另外呢,管道的本身要提供這個,因為提供一個程序之間的一種協調能力啊,協調能力因為,如果讀程序發現根本就沒有寫程序了那麼讀程序就不該再讀了。那麼如果寫程序寫的過程中,發現沒有讀程序了,那麼對方不存在了,是以寫程序也沒必要做,是以它有一個判斷啊對方是否存在這麼一個,同時呢還有一個同步和互斥的問題,如果管道裡頭沒東西了,那麼讀的就得停止,暫停啊暫停,直到有東西進來才能繼續讀那麼,讀寫還不能同時,對吧?是以這樣的話呢,就要注意這個啊互斥問題這就是管道通信方式那麼我們這裡頭隻介紹三種啊程序間通信方式。

繼續閱讀