程序間通訊 (IPC) 方法總結(三)

2022-05-06 08:42:09 字數 3946 閱讀 5733

訊號量是乙個計數器,用於多程序對共享資料的訪問,訊號量的意圖在於程序間同步。

為了獲得共享資源,程序需要執行下列操作:

建立乙個訊號量:這要求呼叫者指定初始值,對於二值訊號量來說,它通常是1,也可是0。

等待乙個訊號量:該操作會測試這個訊號量的值,如果小於0,就阻塞。也稱為p操作。

掛出乙個訊號量:該操作將訊號量的值加1,也稱為v操作。

為了正確地實現訊號量,訊號量值的測試及減1操作應當是原子操作。為此,訊號量通常是在核心中實現的。linux環境中,有三種型別:posix(可移植性作業系統介面)有名訊號量(使用posix ipc名字標識)、posix基於記憶體的訊號量(存放在共享記憶體區中)、system v訊號量(在核心中維護)。這三種訊號量都可用於程序間或執行緒間的同步。

posix有名訊號量

posix基於記憶體的訊號量

system v訊號量

訊號量與普通整型變數的區別

訊號量是非負整型變數,除了初始化之外,它只能通過兩個標準原子操作:wait(semap) , signal(semap) ; 來進行訪問;

操作也被成為pv原語(p**於荷蘭語proberen"測試",v**於荷蘭語verhogen"增加",p表示通過的意思,v表示釋放的意思),而普通整型變數則可以在任何語句塊中被訪問;

訊號量與互斥量之間的區別

互斥量用於執行緒的互斥,訊號量用於執行緒的同步。這是互斥量和訊號量的根本區別,也就是互斥和同步之間的區別。

互斥:是指某一資源同時只允許乙個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。

同步:是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。

在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源

互斥量值只能為0/1,訊號量值可以為非負整數。

也就是說,乙個互斥量只能用於乙個資源的互斥訪問,它不能實現多個資源的多執行緒互斥問題。訊號量可以實現多個同類資源的多執行緒互斥和同步。當訊號量為單值訊號量是,也可以完成乙個資源的互斥訪問。

互斥量的加鎖和解鎖必須由同一執行緒分別對應使用,訊號量可以由乙個執行緒釋放,另乙個執行緒得到。

套接字是一種通訊機制,憑藉這種機制,客戶/伺服器(即要進行通訊的程序)系統的開發工作既可以在本地單機上進行,也可以跨網路進行。也就是說它可以讓不在同一臺計算機但通過網路連線計算機上的程序進行通訊。

套接字是支援tcp/ip的網路通訊的基本操作單元,可以看做是不同主機之間的程序進行雙向通訊的端點,簡單的說就是通訊的兩方的一種約定,用套接字中的相關函式來完成通訊過程。

套接字特性

套接字的特性由3個屬性確定,它們分別是:域、埠號、協議型別。

套接字的域

它指定套接字通訊中使用的網路介質,最常見的套接字域有兩種:

af_inet,它指的是internet網路。當客戶使用套接字進行跨網路的連線時,它就需要用到伺服器計算機的ip位址和埠來指定一台聯網機器上的某個特定服務,所以在使用socket作為通訊的終點,伺服器應用程式必須在開始通訊之前繫結乙個埠,伺服器在指定的埠等待客戶的連線。

af_unix,表示unix檔案系統,它就是檔案輸入/輸出,而它的位址就是檔名。

套接字的埠號

套接字協議型別

流套接字

流套接字在域中通過tcp/ip連線實現,同時也是af_unix中常用的套接字型別。流套接字提供的是乙個有序、可靠、雙向位元組流的連線,因此傳送的資料可以確保不會丟失、重複或亂序到達,而且它還有一定的出錯後重新傳送的機制。

資料報套接字

它不需要建立連線和維持乙個連線,它們在域中通常是通過udp/ip協議實現的。它對可以傳送的資料的長度有限制,資料報作為乙個單獨的網路訊息被傳輸,它可能會丟失、複製或錯亂到達,udp不是乙個可靠的協議,但是它的速度比較高,因為它並一需要總是要建立和維持乙個連線。

原始套接字

原始套接字允許對較低層次的協議直接訪問,比如ip、 icmp協議,它常用於檢驗新的協議實現,或者訪問現有服務中配置的新裝置,因為raw socket可以自如地控制windows下的多種協議,能夠對網路底層的傳輸機制進行控制,所以可以應用原始套接字來操縱網路層和傳輸層應用。比如,我們可以通過raw socket來接收發向本機的icmp、igmp協議包,或者接收tcp/ip棧不能夠處理的ip包,也可以用來傳送一些自定包頭或自定協議的ip包。網路監聽技術很大程度上依賴於socket_raw。

原始套接字與標準套接字的區別

原始套接字可以讀寫核心沒有處理的ip資料報,而流套接字只能讀取tcp協議的資料,資料報套接字只能讀取udp協議的資料。因此,如果要訪問其他協議傳送資料必須使用原始套接字。

套接字通訊的建立

eg.服務端**

#include #include #include //socket listen bind

#include //socket listen bind

#include //unlink

#include //struct sockaddr_un

int main()

return 0;

}

客戶端**

#include #include #include //socket listen bind

#include //socket listen bind

#include //unlink

#include //struct sockaddr_un

int main()

/* exchange data */

char ch = 'a';

write(sockfd, &ch, 1);

read(sockfd, &ch, 1);

printf("get char from server: %c\n", ch);

/* close the socket */

close(sockfd);

return 0;

}

如果我們首先執行tcp_client,會提示沒有這個檔案:

因為我們是以af_unix方式進行通訊的,這種方式是通過檔案來將伺服器和客戶端連線起來的,因此我們應該先執行tcp_server,建立這個檔案,預設情況下,這個檔案會建立在當前目錄下,並且第乙個s表示它是乙個socket檔案:

程式執行的結果如下圖:

參考文章:

程序間通訊ipc (interprocess communication)

程序間通訊--管道

unix/linux程序間通訊ipc系列(四)訊息佇列

linux程序間通訊(四) - 共享記憶體

本地socket通訊

程序間通訊(IPC)總結

管道 使用簡單 fifo 非血緣關係間 訊號 開銷小 共享記憶體 非血緣關係間 本地套接字 穩定性好 訊號 sinal 訊號是一種比較複雜的通訊方式,用於通知接收程序某個事件已經發生。unix domain socket是全雙工的,api介面語義豐富,相比其它ipc機制有明顯的優越性,目前已成為使用...

程序間通訊 IPC 方法

程序間通訊 ipc 方法主要有以下幾種 管道 fifo 共享記憶體 訊息佇列 訊號量 1.管道中還有命名管道和非命名管道 即匿名管道 之分,非命名管道 即匿名管道 只能用於父子程序通訊,命名管道可用於非父子程序,命名管道就是fifo,管道是先進先出的通訊方式 2.訊息佇列是用於兩個程序之間的通訊,首...

程序間通訊IPC

這兩天學習了 unix 的程序間通訊 ipc,這裡面有幾個很重要的基本概念,特別是訊息佇列和我的畢設很有關係,因此多說幾句。以前學習的程序間通訊方式,一般都是經由 fork 或exec 開啟檔案,或經過檔案系統。而 ipc是程序間通訊方式的統稱。下面一一道來。一 管道 管道是最老的 ipc形式。管道...