程序間通訊1

2021-08-06 05:16:18 字數 3986 閱讀 7505

管道通訊

管道是單向、先進先出的,他把乙個程序的輸出和另乙個程序的輸入連在一起。

兩個程式之間傳遞資料的一種簡單方法是使用popen和pclose。

#include 

file *popen(const

char *command, const

char *type);

int pclose(file *stream);

popen函式允許乙個程式將另乙個程式作為新程序來啟動,並可以傳遞資料給它或者通過它接收資料。command字串是要執行的程式名和相應的引數。type必須是」r」或」w」。

如果type是」r」,被調程式的輸出就可以被呼叫程式使用,呼叫程式利用popen函式返回的file *檔案流指標,可以讀取被調程式的輸出;如果type是」w」,呼叫程式就可以向被調程式傳送資料,而被調程式可以在自己的標準輸入上讀取這些資料。

pclose函式只在popen啟動的程序結束後才返回。如果呼叫pclose時它仍在執行,pclose將等待該程序的結束。

管道型別

無名管道:用於父子程序之間的通訊。

無名管道由pipe()函式建立:

int pipe(int filedis[2]);

當乙個管道建立時,它會建立兩個檔案描述符:

filedis[0]用於讀管道,filedis[1]用於寫管道。

順序不能顛倒。

//**例子

#include

#include

#include

#include

int main()

else

close(pipe_fd[0]);

close(pipe_fd[1]);

return

0;}

管道用於不同程序間通訊,通常先建立乙個管道,再用fork()函式建立乙個子程序,該子程序會繼承父程序所建立的管道描述符。必須在fork()前呼叫pipe(),否則子程序將不會繼承檔案描述符

#include 

#include

#define size 1024*100

int main()

ret = write (fd[1], "hello", 5);

printf ("寫入 %d 個位元組\n", ret);

char ch;

while (1)

printf ("讀到 %d 個位元組: %c\n", ret, ch);

}close (fd[0]);

close (fd[1]);

return

0;}

#include 

#include

int mkfifo(const

char *pathname, mode_t mode);

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

pathname: fifo檔名

mode:屬性(同檔案操作)

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

當開啟fifo時,非阻塞標識(o_nonblock)將對以後的讀寫產生影響:

1、沒有使用o_nonblock:訪問要求無法滿足時程序將阻塞。如果試圖讀取空的fifo,將導致程序阻塞。

2、使用o_nonblock:訪問要求無法滿足時不阻塞,立刻出錯返回。errno是enxio。

共享記憶體

共享記憶體實現分兩個步驟:

1、建立共享記憶體,使用shmget函式

2、對映共享記憶體,將這段建立的共享記憶體對映到具體的程序空間去,使用shmat函式。

int shmget(key_t key, int size, int shm***)

key:

1、0/ipc_private:當key的取值為ipc_private,則函式shmget()將建立一塊新的共享記憶體;如果key取值為0,而引數shm***中又設定ipc_private這個標誌,則同樣會建立一塊新的共享記憶體。

2、大於0的32位整數:視引數shm***來確定操作。

size:

1、大於0的整數:新建的共享記憶體大小,以位元組為單位0:

2、只獲取共享記憶體時指定為0

shm***:模式標誌引數,使用時需要與ipc物件訪問許可權(如0600)進行|運算來確定共享記憶體的訪問許可權

1、0:取共享記憶體識別符號,若不存在則函式會報錯

2、ipc_creat:當shm***&ipc_creat為真時,如果核心中不存在鍵值與key相等的共享記憶體,則新建乙個共享記憶體;如果存在這樣的共享記憶體,返回此共享記憶體的識別符號

3、ipc_creat|ipc_excl:如果核心中不存在鍵值 與key相等的共享記憶體,則新建乙個共享記憶體;如果存在這樣的共享記憶體則報錯

返回值:如果成功,返回共享記憶體識別符號;如果失敗,返回-1。

void* shmat(int shmid, char *shmaddr, int flag)

引數:

第乙個引數,shm_id是由shmget函式返回的共享記憶體標識。

第二個引數,shm_addr指定共享記憶體連線到當前程序中的位址位置,通常為空,表示讓系統來選擇共享記憶體的位址。

第三個引數,shm_***是一組標誌位,通常為0。

返回值:

如果成功,則返回共享記憶體對映到程序中的位址;如果失敗,則返回-1。

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

引數shmaddr是shmat函式返回的位址指標,呼叫成功時返回0,失敗時返回-1.

該函式用於將共享記憶體從當前程序中分離。注意,將共享記憶體分離並不是刪除它,只是使該共享記憶體對當前程序不再可用。

int shmctl(int shm_id, int command, struct shmid_ds *buf);

第乙個引數,shm_id是shmget函式返回的共享記憶體識別符號。

第二個引數,command是要採取的操作,它可以取下面的三個值 :

ipc_stat:把shmid_ds結構中的資料設定為共享記憶體的當前關聯值,即用共享記憶體的當前關聯值覆蓋shmid_ds的值。

ipc_set:如果程序有足夠的許可權,就把共享記憶體的當前關聯值設定為shmid_ds結構中給出的值

ipc_rmid:刪除共享記憶體段

第三個引數,buf是乙個結構指標,它指向共享記憶體模式和訪問許可權的結構。

shmid_ds結構至少包括以下成員:

struct shmid_ds

;

**例子

#include 

#include

#include

#include

#include

typedef

struct _shm

shm;

int main()

//2.將共享記憶體對映到當前的程序中

shm *pshm = (shm*)shmat(shmid, null, 0);

if (pshm == -1)

strcpy (pshm->msg, "hello");

//解除共享記憶體對映,解除的是當前程序不再使用共享記憶體

shmdt(pshm);

shmctl(shmid, ipc_rmid, struct null);

return

0;}

程序間通訊1

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

程序間的通訊(1)

根據程序間通訊資訊量的不同,劃分為兩個類別 控制資訊的通訊 低階通訊 和大批量資料資訊的通訊 高階通訊 常見的通訊介面有 用於實現低階通訊的有軟中斷訊號 訊號量集,實現高階通訊的有管道 訊息佇列 共享記憶體等。軟中斷訊號 是作業系統用來通知程序有事件發生的一種訊號機制,用於實現簡單的非同步通訊的一些...

程序間通訊(1) 管道

linux下一切皆檔案,我們可以建立乙個管道檔案進行通訊,實際上是呼叫pipe函式在核心中開闢一塊緩衝區 稱為管道 用於通訊,管道是一種最基本的ipc機制,由pipe函式建立 include int pipe int filedes 2 它有乙個讀端乙個寫端,然後通過filedes引數傳出給使用者程...