程序的五種通訊方式
阿新 • • 發佈:2019-01-24
一、管道
1、什麼是管道
我們把一個程序連線到另一個程序的資料流稱為一個管道。它是最古老的程序通訊形式。
2、原型(匿名管道):
#include <unistd.h>
功能:建立⼀⽆名管道
原型
int pipe(int fd[2]);
引數
fd:⽂件描述符陣列,其中fd[0]表⽰讀端, fd[1]表⽰寫端
返回值:成功返回0,失敗返回錯誤程式碼
3.管道的特點
(1).只能用於擁有共同祖先的程序進行通訊,通常一個程序先建立管道,然後該程序呼叫fork,然後父子程序便可以一同應用此管道。
(2).管道提供流式服務。
(3).一般而言,程序退出管道釋放,管道的生命週期隨程序。
(4).一般而言,核心會對管道操作進行同步與互斥。
(5).管道是半雙工,資料只能向一個方向流動,如果要實現雙方通訊時,則需要建立兩個管道。
二、命名管道
1.建立原因:管道本只能在擁有共同祖先的程序之間通訊,若想在無關程序之間通訊,那麼則使用FIFO檔案來實現,被稱為命名管道。
2.建立命名管道
(1)命名管道可以從命令列建立
$ mkfifo filename
(2).命名管道也可以在程式中建立
int mkfifo(const char* filename, mode_t mode);
(3)建立命名管道
int main(int argc, char *argv[]) { mkfifo("p2", 0644); return 0; }
3.匿名管道與命名管道的區別:
- 匿名管道由pipe建立並開啟
- 命名管道由mkfifo建立,由open開啟
- 兩者唯一的區別就是建立和開啟的方式不同,一旦這些完成之後,他們具有相同的語義
三、訊息佇列
1、概念
- 訊息佇列提供了從一個程序向另一個程序傳送一塊資料的方法。
- 每個資料塊都被認為是有一個型別,接收者程序接收的資料塊可以有不同的型別。
- 訊息佇列的不足是訊息佇列有最大長度的限制(MSGMAX),並且還有位元組數的限制(MSGMNB),訊息佇列的總數也有限制(MSGMNI)。
2.原型:
(1).msgget()函式
功能:⽤來建立和訪問⼀個訊息佇列 原型 int msgget(key_t key, int msgflg); 引數 key: 某個訊息佇列的名字 msgflg:由九個許可權標誌構成,它們的⽤法和建立⽂件時使⽤的mode模式標誌是⼀樣的 返回值:成功返回⼀個⾮負整數,即該訊息佇列的標識碼;失敗返回-1
(2)msgctl()函式
功能:訊息佇列的控制函式
原型
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
引數
msqid: 由msgget函式返回的訊息佇列標識碼
cmd:是將要採取的動作,(有三個可取值)
返回值:成功返回0,失敗返回-1
(3)msgsnd()函式
功能:把⼀條訊息新增到訊息佇列中
原型
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
引數
msgid: 由msgget函式返回的訊息佇列標識碼
msgp:是⼀個指標,指標指向準備傳送的訊息,
msgsz:是msgp指向的訊息⻓度,這個⻓度不含儲存訊息型別的那個long int⻓整型
msgflg:控制著當前訊息佇列滿或到達系統上限時將要發⽣的事情
msgflg=IPC_NOWAIT表⽰佇列滿不等待,返回EAGAIN錯誤。
返回值:成功返回0;失敗返回-1
(4).msgrcv()函式
功能:是從⼀個訊息佇列接收訊息
原型
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
引數
msgid: 由msgget函式返回的訊息佇列標識碼
msgp:是⼀個指標,指標指向準備接收的訊息,
msgsz:是msgp指向的訊息⻓度,這個⻓度不含儲存訊息型別的那個long int⻓整型
msgtype:它可以實現接收優先順序的簡單形式
msgflg:控制著佇列中沒有相應型別的訊息可供接收時將要發⽣的事
返回值:成功返回實際放到接收緩衝區⾥去的字元個數,失敗返回-1
四、共享記憶體
(1).shmget函式
功能:⽤來建立共享記憶體
原型
int shmget(key_t key, size_t size, int shmflg);
引數
key:這個共享記憶體段名字
size:共享記憶體⼤⼩
shmflg:由九個許可權標誌構成,它們的⽤法和建立⽂件時使⽤的mode模式標誌是⼀樣的
返回值:成功返回⼀個⾮負整數,即該共享記憶體段的標識碼;失敗返回-1
(2).shmat函式
功能:將共享記憶體段連線到程序地址空間
原型
void *shmat(int shmid, const void *shmaddr, int shmflg);
引數
shmid: 共享記憶體標識
shmaddr:指定連線的地址
shmflg:它的兩個可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回⼀個指標,指向共享記憶體第⼀個節;失敗返回-1
(3).shmdt函式
功能:將共享記憶體段與當前程序脫離
原型
int shmdt(const void *shmaddr);
引數
shmaddr: 由shmat所返回的指標
返回值:成功返回0;失敗返回-1
注意:將共享記憶體段與當前程序脫離不等於刪除共享記憶體段
(4).shmctl函式
功能:⽤於控制共享記憶體
原型
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
引數
shmid:由shmget返回的共享記憶體標識碼
cmd:將要採取的動作(有三個可取值)
buf:指向⼀個儲存著共享記憶體的模式狀態和訪問許可權的資料結構
返回值:成功返回0;失敗返回-1
五、訊號量
訊號量本質上是一個計數器
訊號量結構體虛擬碼:
struct semaphore
{
int value;
pointer_PCB queue;
}