程序間通訊

2021-06-21 16:30:17 字數 2908 閱讀 2187

一、   為什麼程序間需要通訊

1 資料間傳輸  

乙個程序需要將它的資料傳送給另乙個程序。

2資源共享

多個程序共享同樣的資源  進行協調

3 通知時間

乙個程序需要向另乙個或一組程序傳送訊息,通知它們發生了某種事件。

4 程序控制

有些程序希望完全控制另乙個程序的執行,此時控制程序希望能夠攔截另乙個程序的所有操作,並能夠及時知道它的狀態改變。

常用的程序間通訊方式

1管道(pipe)和有名管道(fifo)            2訊號(signal)         3訊息佇列          4共享記憶體           5訊號量            6套接字

1  管道通訊

1)管道是單向的、先進先出的,它把乙個程序的輸出和另乙個程序的輸入連線在一起。乙個程序在管道(寫程序)的尾部寫入資料,另乙個程序(讀程序)從管道的頭部讀出資料。

2)管道建立

管道包括無名管道和有名管道兩種,前者用於父程序和子程序間的通訊。後者可用於執行與同一系統中的任意兩個程序間的通訊。無名管道建立用函式int pipe(int pipedis[2]).當不需要管道時,進行關閉。

不同程序間需要fork()乙個子程序。子程序進行讀管道,父程序進行寫入管道。必須在系統呼叫fork()前呼叫pipe(),否則子程序將不會繼承檔案描述符。

#include

#include

int mkfifo(const char* pathname,mode_t mode)

pathname:fifo檔名

mode:屬性   一旦建立了乙個fifo,就可以用open開啟它,一般的檔案訪問函式(close\read\write等)都可用於fifo。

2訊號通訊

1)訊號機制是unix系統中最為古老的程序間通訊機制,很多條件可以產生乙個訊號:

當使用者按某些按鍵時,產生訊號;

硬體異常產生訊號,除數為0、無效的儲存訪問等等。這些情況通常由硬體檢測到,將其通知核心,然後核心產生適當的訊號通知程序,例如,核心對正訪問乙個無效儲存區的程序產生乙個sigsegv訊號。

1忽略  除了isgkill與sigstop  2執行使用者希望的動作   3 執行系統預設動作

傳送訊號的主要函式有kill和raise.kill既可以給自身傳送訊號也可以向其他程序傳送訊號。raise函式是向程序自身傳送訊號。alarm可以設定乙個時間值,當所設定的時間到了時,產生乙個isgalarm訊號,如果不撲捉此訊號,則預設動作是終止該程序。pause函式使呼叫程序掛起直至捕捉到乙個訊號。int pause(void).

訊號處理的主要方法有兩種,一種是使用簡單的signal函式,另一種是使用訊號集函式組。

#include

void (*signal(int signo,void (*func)(int)))(int)  signal是乙個函式指標,第乙個是signo,第二個引數是乙個函式指標  返回型別還是乙個函式指標

理解為:

typedef void (*sighandler_t)(int)

sighandler_t signal(int signum,sighandler_t handler)   用ps aux檢視程序號

共享記憶體:

建立加對映!當乙個程序不再需要共享記憶體時,需要把它從程序位址空間中脫離。int shmdt(char*  shmaddr );

訊息佇列:

訊號能傳送的資訊量有限,管道則只能傳送無格式的位元組流,這無疑會給應用程式開發帶來不便。訊息佇列也叫做報文佇列則客服了這些缺點。

訊息佇列就是乙個訊息的鍊錶,可以把訊息看做乙個記錄,具有特定的格式。程序可以向中按照一定的規則新增新訊息。另一些程序則可以從訊息佇列中讀走訊息。

posix訊息佇列以及系統v訊息佇列。系統v訊息佇列目前被大量使用。

系統v訊息佇列是隨核心持續的,只有在核心重啟或者人工刪除時,該訊息佇列才會被刪除。

訊息佇列的核心持續性要求每個訊息佇列都在系統範圍內對應唯一的鍵值,所以,要獲得乙個訊息佇列的描述字,必須提供該訊息佇列的鍵值。

key_t ftok(char* pathname,char proj);功能:返回檔名對應的鍵值   pathname:檔名  proj:專案名(不為0即可)

int  msgget(key_t key,int msg***)

key:鍵值,由ftok獲得。msg***:標誌位  ipc_create   ipc_excl  ipc_nowait 返回值:與鍵值key相對應的訊息佇列描述字。

建立新的訊息佇列條件:

沒有與鍵值key相對應的訊息佇列並且msg***中包含了ipc_create標誌位。   key引數為ipc_private.

int   open_queue(key_t keyval)

int qid;

if((qid=msgget(keyval,ipc_create))==-1)建立乙個訊息佇列

{ return -1;

return(qid);

int msgsnd(int msqid,struct msgbuf* msgp,int msgsz,int msg***)想訊息佇列中傳送一條訊息

struct  msgbuf

long mtype;

char mtext[1];

int msgrcv(int msqid,struct msgbuf* msgo,int msgsz,long msgtyp,int msg***)功能是從msqid代表的訊息佇列中讀取乙個msgtyp型別的訊息,並把訊息儲存在msgp指向的msgbuf結構中,在成功地讀取了一條訊息以後,佇列中的這條訊息將被刪除。

訊號量:訊號量與其他程序間通訊方式不大相同,主要用途是保護臨界資源。程序可以根據它判斷是否能夠訪問某些共享資源,除了用於訪問控制外,可以用於程序同步。

訊號量是乙個整數。二值訊號量只能取0或1,類似於互斥鎖。計數訊號燈:訊號燈的值可以取任意非負值。

php程序間通訊 yoc PHP程序間通訊

php是用c編寫的,因此它對系統底層api的操作與c很像,同大多數語言一樣,php程序間通訊的方式有以下幾種 訊息佇列,管道,共享記憶體,socket和訊號。本文是對這幾種通訊方式對整理 管道通訊pipe 管道用於承載簡稱之間的通訊資料。為了方便理解,可以將管道比作檔案,程序a將資料寫到管道p中,然...

程序間通訊

實現程序間資料共享除了常用的記憶體檔案對映外,對於一些非檔案的資料共享可以直接使用wm copydata。如果需要在程序a傳遞資料到程序b,簡單的實現如下 在程序a中 cstring strdatatosend t hello 需要傳遞的資料 hwnd hwndreceived 程序b的接收資料視窗...

程序間通訊

最近做專案遇到奇怪的問題,我在主線程中建立乙個工作執行緒。在工作執行緒中用sendmessage向主線程傳送訊息,通知主線程操作office 物件。getactiveobject時提示 hr 0x8001010d 因為應用程式正在傳送乙個輸入同步呼叫,所以無法執行傳出的呼叫。我把sendmessag...