初學Linux 程序間通訊(共享記憶體 訊號量)

2021-08-07 17:18:43 字數 2741 閱讀 3108

基本概念

系統核心分配的一塊儲存區,該記憶體被對映到多個程序的各自的程序位址空間,多個程序都可以對共享記憶體中資料進行跟新。

1.程式設計模型:

首先用shmget建立乙個共享記憶體,再呼叫shmat將共享記憶體對映至呼叫程序的位址空間。對映完成後通過返回的共享記憶體的讀寫指標進行讀寫,最後呼叫shmdt關閉共享記憶體的對映。

2.對映:

共享記憶體建立後,使用者程式執行時,通過呼叫ipc介面函式將該儲存區對映至應用程式的記憶體位址空間。成功對映後就可對共享記憶體的讀寫像讀寫程序一樣快捷。

3.資料結構:

與其他ipc機制一樣,共享記憶體也有鍵值與識別符號。共享記憶體有訪問計數器機制,每有乙個程序進行一次共享記憶體的對映,計數器就會+1,解除-1,當訪問計數器=0時,可真正解除。可以通過執行命令ipcs-m的輸出項nattch檢視共享記憶體的訪問計數。共享記憶體建立後,系統核心為該共享記憶體分配了控制結構,該結構名為struct shmid_ds。位於中。

共享記憶體程式設計

1.建立共享記憶體:

#include

int shmget(key_t_key,size_t_size,int_shm***);

2.對映共享記憶體:

#include

void*shmat(int_shmid,_const void*_shmaddr,int_shm***);

3.刪除共享記憶體對映:

#include

int shmdt(_cosnt void*_shmaddr);

4.控制共享記憶體:

#include

int shmctl(int_shmid,int _cmd,struct shmid_ds*_buf);

_buf:指向shmid_ds結構的指標,在_cmd為ipc_stat時,該引數用作輸出,_cmd為ipc_set時,用作輸入。

pv操作原理

1.定義:

pv操作是兩個操作的合稱,這兩個操作分別是p操作和v操作。p是指通過,v是指釋放。他們都是一種作業系統「原語」是指不可中斷的過程,即兩者都是原子操作。pv操作的前提是假定存在整型變數sem,pv操作就是對其進行加減的過程。

p操作過程定義如下:

(1).sem減1;(2).若sem減一後仍然大於等於零,則p操作返回,該程序繼續進行;(3).若sem減一後小於零,則該程序被阻塞,進入作業系統的阻塞佇列。

v操作過程定義如下:

(1).sem加1;(2).若sem加一後大於零,則v操作返回,該程序繼續進行;(3).若sem加一後小於等於零,則從作業系統的阻塞佇列中喚醒乙個阻塞在該訊號量上的程序,然後再返回原程序繼續執行。

2.pv操作的應用:

1.程序互斥:假設系統中存在乙個檔案,兩個程序ab對其進行寫,如果單獨進行不會存在問題,但如果程序ab同時對檔案進行寫,那麼會導致檔案內容混亂。可以使用pv操作解決這個問題,首先定義乙個訊號量,其初始值為1.在程序a向檔案寫之前,先用p操作原語鎖定資源,此時資源可用,p操作成功後。程序a開啟向其中寫入資料。寫完後,關閉檔案並呼叫v操作原語釋放資源。程序b的操作過程相同。這樣資源同一時刻只能被乙個程序呼叫。

偽**:

p(sem);

writefile;

v(sem);

2.程序同步:在多程序程式設計環境下,有時乙個程序需要暫時阻塞,等待另乙個程序進行相應處理。程序b結束後,程序a再繼續進行。這種情況下,需要程序同步。pv操作解決這個問題:在系統中定義一訊號量,初始值為0,程序a執行計算任務,執行完成後呼叫v操作通知程序b進行,程序b一開始就執行p操作,等待程序a結束。

訊號量的基本概念

linux的訊號量機制在標準pv操作基礎上進行了擴充,主要體現為:

- linux支援訊號組

- 每次訊號量的pv操作不僅限於對訊號量值加一或減一,而是加減任意數。

- 支援程序退出時回滾對訊號量的修改。

訊號量的控制結構:

struct semid_ds

位於標頭檔案

訊號量程式設計

1.建立訊號量:

#include

int semget(key_t_key,int_nsems,in_sem***);

_key:鍵值

_nsems:訊號量集中的訊號量的個數

_sem***:建立訊號量標誌,主要包括兩方面資訊:1.訪問許可權資訊,該資訊將初始化訊號量控制結構中的sem_perm許可權結構,2.建立標誌。

2.訊號量操作:

#include

int semop(int _semid,struct sembuf*_sops,size_t_nsops);

_semid:訊號量集的識別符號。

_sops:訊號量集的操作快取,實際是乙個指向結構陣列的指標,該結構定義如下:

struct sembuf;
3.訊號量控制:

#include

int semctl(int_semid,int_semnum,int_cmd,...);

參考《linux程式設計從入門到精通》

Ubuntu下Linux程序間通訊 共享記憶體

linux提供了多種程序間通訊的方法,常見有管道 匿名 fifo 有名管道 訊息佇列 訊號量 共享記憶體,socket通訊。linux程序間通訊 匿名管道 linux程序間通訊 fifo 有名管道 linux程序間通訊 訊息佇列 linux程序間通訊 訊號量 linux程序間通訊 共享記憶體 5.共...

Linux高階程式設計基礎 程序間通訊之共享記憶體

建立共享記憶體,寫程序每隔2秒向記憶體寫入一次 hello world 如果結束寫操作,則寫程序寫入 end 讀程序從共享記憶體讀取資料,並列印。直到讀到 end 為止。這是寫程序 include include include include include include include inc...

Linux程序間通訊 共享記憶體

共享記憶體是執行在同一臺機器上的程序間通訊最快的方式,因為資料不需要在不同的程序間複製。通常由乙個程序建立一塊共享記憶體區,其餘程序對這塊記憶體區進行讀寫。共享記憶體往往與其它通訊機制,如訊號量結合使用,來達到程序間的同步及互斥。首先要用的函式是shmget,它獲得乙個共享儲存識別符號。i nclu...