程序通訊(1)

2021-09-08 17:06:17 字數 4442 閱讀 7940

在多道程式系統中,為了協調程序之間的工作,併發程序經常需要交換資訊,尤其是乙個作業中的多個程序之間,為了合作完成一項任務,有時還要交換大批資料。程序之間的資訊交換稱為程序間通訊(interprocess communication,ipc)。

程序之間只需要交換少量的控制訊號(如訊號量)就可以實現彼此的同步,但是,為了同步而交換的控制資訊並不是程序通訊的目的,最終的目標是,在條件合適時,交換大量的純資料,它不僅是為了控制雙方的推進速度(p/v原語),而且為了讓對方能接受到資料,進而對資料進行處理。

根據程序之間互動資訊的型別,可把程序通訊分為低階通訊和高階通訊兩類。所謂低階通訊是指程序之間交換少量的控制資訊,以實現程序的同步和互斥;而高階通訊是程序間交換大量的資料,以實現資料的處理。低階通訊交換的是控制資訊,資訊量少、效率低;高階通訊交換的是普通資料,資料量大、通訊效率高,這裡主要介紹高階通訊。

1、最早的ipc方法:訊號與通道

訊號是用整數表示的系統非同步事件,訊號最初用於表示硬體錯誤(浮點溢位、訪問越界),系統核心將其轉換為訊號,通知相應的程式做出相應的處理。它是系統中程序間的一種低階通訊形式。

linux系統中所支援的訊號型別與具體的平台相關,由於核心中用乙個字代表所有的訊號,每個位對應一種訊號,所以訊號型別的最大數目取決於機器的長度。例如32位字長的處理機最多支援32種訊號,部分訊號如下:

巨集名用途

巨集名用途

sighup

從中斷發出的結束訊號

sigkill

結束接受訊號的程序

sigint

來自鍵盤的中斷訊號ctrl+c

sigalrm

定時訊號

sigquit

來自鍵盤的退出訊號ctrl+\

sigterm

kill命令發出的訊號

sigfpe

浮點異常訊號

sigchld

標誌子程序結束或停止的訊號

訊號機制的最大特點就是非同步性,乙個程序可以在任意時刻接受訊號,但是只有當程序進入執行狀態時才能對接受訊號做出響應,這種現象與中斷類似,為了區別於硬體中斷,訊號又稱「軟中斷」。只有核心和超級使用者可以向其他程序傳送訊號,普通程序只能向具有相同uid和gid的程序或同一程序組的其他程序傳送訊號。

訊號的傳送通過設定程序task_struct結構中的signal域中的某一位產生的,每次程序從系統呼叫中退出時,都會檢查signal和blocked域,檢查是否有立刻可以傳送的訊號。

linux系統中,訊號之間無優先關係,同類訊號也無特定原則。當多個訊號同時傳送時,程序可以以任意順序接收到,也可以按任意次序處理。在程序的task_struct中有乙個指標指向sigaction陣列,陣列的每乙個元素記錄了程序待處理的訊號及處理每個訊號的程式的入口位址。訊號的處理有很多種,完全由接受者來決定,可歸納為四類:

1.忽略訊號:程序可忽略除某些訊號之外的所有訊號。首先檢查sigaction陣列,如果訊號不是sigkill和sigstop且被忽略時,則不對該訊號做任何處理;

2.阻塞訊號:程序可以阻塞某些訊號;

3.由程序處理該訊號:程序可以在系統中註冊處理訊號的處理程式位址,接受該訊號時由註冊的處理程式處理訊號;

4.由核心進行預設處理:大多數情況,訊號由核心處理。

linux中有關訊號的訊號呼叫如下所示:

呼叫原型

功能int signal(int signum,void(*handler)(int))

傳送訊號

int sigaction(sig,&handler,&oldhandler)

定義與訊號的處理

int sigprocmask(int how,sigset_t *mask,sogset_t *old)

檢查或修改訊號遮蔽

int pause(void)

掛起程序

管道通過共享檔案方式實現大批資料的傳送,是linux系統中的一種高階通訊方式。實際上,linux系統中的管道是由檔案系統的高速緩衝區實現的,其容量被限定在4kb。程序通過管道傳送資訊時,首先建立乙個管道檔案將寫程序與讀程序聯絡起來,此後,寫程序可將資訊寫入管道檔案中,而讀程序可以從管道檔案中讀出資訊。

這種通訊本質上是乙個生產者/消費者方式工作的環形緩衝區問題,但其部分同步和互斥工作已由作業系統完成。例如當緩衝區已經滿時,作業系統會自動阻塞寫程序write(),直至資料被取走;讀程序每次從管道中讀取資料,系統就會將這部分資料刪除。當管道為空時,系統會阻塞讀程序read()。

在linux中,大多數shell命令支援管道操作,它可以將乙個程序的標準輸出送到下乙個程序的標準輸入中,實現多個程序間的單向傳送,形式如下:

命令1|命令2|...|命令n

在linux中,管道將兩個檔案描述符指向同一臨時的虛擬檔案系統的inode,而該vfs inode指向記憶體中的乙個物理頁面。其中,乙個file結構實現對管道檔案的寫操作,而另乙個實現對檔案的讀操作,頁面就是讀/寫程序共享的緩衝區。寫程序將資料複製到頁面的尾部;讀程序從頁面的頭部複製資料。

linux下管道分兩種:無名管道和命名管道。無名管道就是一般意義上的管道,通過系統呼叫pipe建立臨時檔案,物理上由高速緩衝區構成,很少啟用外設。程序通訊完成後,系統**檔案的索引節點。無名管道只能有管道的建立者及其子程序使用。命名管道,即fifo管道,是乙個按名訪問的檔案,可以在檔案系統中長期存在,任一程序都可按通常的檔案儲存方法訪問命名管道。無名管道的操作如下:

1.建立管道——pipe():原型int pipe(int fd[2]),建立無名管道,如果系統呼叫成功,返回0;如果失敗返回-1。管道建立後,管道兩端可分別用描述字fd[0]以及fd[1]來描述,其中,fd[0]只用於讀,稱為管道讀端;fd[1]只用於寫,稱為管道寫端。

2.向管道寫入資料——write(fd[1],buf,size):寫入資料時,先檢測管道是否有足夠空間?記憶體是否被讀程序鎖住?如果都滿足則增加管道的大小,寫入所有資料。

3.從管道中讀出資料——read(fd[0],buf,size)讀取資料。

4.關閉管道的一端——close(fd[i])

簡單舉例:子程序向管道中寫入資料,父程序從管道中讀取資料。

#include#include

#include

int main(void)

if(child == 0

)

else

return(0

);}

無名管道的特點是簡單、高效,但也存在一些缺陷:只支援單向資料流,不支援全雙工通訊;家族關係的程序之間;緩衝區大小有限;傳送的是無格式位元組流,發收雙方要事先約定規則;管道中資訊不能長久儲存。

命名管道(fifo管道),是在無名管道之上,克服無名管道的缺陷而提出的一種按名訪問的檔案,可在檔案系統中長期存在,任何程序都可以按檔案訪問方法操作管道。系統呼叫:

1.建立命名管道

int mkfifo(const char *pathname,mode_t mode);

int mknod(char *pathname,mode_t mode,dev_t dev);

第乙個引數是fifo的名稱,第二個mode與檔案open()函式的引數mode相同。

2.開啟管道open,操作前需要先開啟管道。

3.管道的讀/寫,與無名管道相同。

/*

fifo_write.c

*/#include

#include

#include

#include

#include

#include

#include

#define fifo_server "/tmp/myfifo"main(

int argc,char**ar**)

else

printf(

"write %s to the fifo\n

",w_buf);}/*

fifo_read.c

*/#include

#include

#include

#include

#include

#include

#include

#define fifo "/tmp/myfifo"main(

int argc,char**ar**)

while(1)

printf(

"read %s from fifo\n

",buf_r);

sleep(1);

} pause();

unlink(fifo);

}

計算機系統的硬體結構主要由四部分組成:控制器、運算器、記憶體和輸入輸出裝置,其中,控制器和運算器統稱為**處理器。簡稱cpu,它是計算機硬體系統的指揮中心。其中,控制器的功能是
控制計算機各部分協調工作

,運算器則是負責計算機的算術運算和邏輯運算。運算器包括:算術邏輯運算單元alu、浮點運算單元fpu、通用暫存器組和專用暫存器;控制器包括:指令控制器、時序控制器、匯流排控制器和中斷控制器。

程序通訊1 管道通訊

管道是單向的 先進先出的,它把乙個程序的輸出和另乙個程序的輸入連線在一起。乙個程序 寫程序 在管道尾部寫入資料,另乙個程序 讀程序 從管道的頭部讀出資料。兩個程式之間傳遞資料的一種簡單方法是使用popen和pclose。include file popen const char command,co...

程序間通訊1

管道由於傳遞資料只能單向傳遞,因此又稱半雙工管道,它是一種兩個程序間進行單向通訊的機制 侷限性 資料只能由乙個程序流向另乙個程序,若要進行全雙工通訊,則需建立兩個管道 管道只能用於具有親緣關係的程序間通訊 管道無名字 管道的緩衝區大小受限制 管道所傳遞的是無格式的位元組流,這就要求管道的輸入和輸出事...

程序間通訊1

管道通訊 管道是單向 先進先出的,他把乙個程序的輸出和另乙個程序的輸入連在一起。兩個程式之間傳遞資料的一種簡單方法是使用popen和pclose。include file popen const char command,const char type int pclose file stream ...