1.進程通信的目的
????(1) 數據傳輸: 一個進程需要將它的數據傳輸給另一個進程
????(2) 資源共享: 多個進程之間共享同樣的資源
????(3) 通知事件: 一個進程需要向另一個或一組進程發送消息, 通知它們發生了什么事情
2.管道
????管道是一種進程之間通信的一種方式, 我們把從一個進程連接到另一個進程的數據流叫做管道
3.匿名管道
????(1) 匿名管道的創建
int pipe(int fd[2]);
fd是一個文件描述符數組, fd[0] 代表讀端, fd[1] 代表寫端
返回值:成功過時返回0, 失敗時返回錯誤代碼
4.代碼演示
//clientPipe.c
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<stdlib.h>int main()
{int wfd = open("mypipe", O_WRONLY);if(wfd == -1)//dakashibai{perror("open");exit(1);}char buf[1024];buf[0] = 0;ssize_t s;while(1){printf("Please Enter#");fflush(stdout);s = read(0, buf, sizeof(buf));if(s > 0)//成功讀取{buf[s] = 0;write(wfd, buf, s);}else if(s <= 0)//讀取失敗{perror("read");exit(1);}}
}//serverPipe.c
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/types.h>int main()
{int fifo = mkfifo("mypipe", 0644);if(fifo == -1)//管道創建失敗{perror("mkfifo");exit(1);}//打開管道int rfd = open("mypipe", O_RDONLY);if(rfd == -1)//打開失敗{perror("open");exit(1);}//讀管道數據char buf[1024];ssize_t s;while(1){buf[0] = 0;printf("Please wait ... \n");s = read(rfd, buf, sizeof(buf) -1);if(s > 0)//讀到數據{buf[s] = 0;printf("client say# %s", buf);}else if(s == 0)//讀完{printf("client quit, exit now\n");exit(0);}else//讀取失敗{perror("read");exit(1);}}close(rfd);return 0;
}
?????????????
5.站在文件描述符角度理解
????父進程先創建管道, 創建完管道,同時父進程打打開對應的讀端和寫端,接著父進程創建子進程, 由于子進程會繼承父進程的特性, 因此子進程也會打開和父進程一樣的讀端和寫端, 此時父子進程就看到了一份公共資源, 緊接著父進程將讀端關閉, 子進程將寫端關閉, 于是便可以父進程進行對數據的寫,子進程只管從管道中讀數據即可,于此父子進程合作完成讀寫工作.
6.管道讀寫規則
???? (1) 當管道讀端關閉, 寫端還在繼續寫的時候此時操作系統會給寫端發送一個 SIGPIPE 的信號,從而使得寫端退出
???? (2) 如果寫端對應的描述符關閉, 讀端則會正常退出.
???? (3) 管道具有上限,當寫到 PIPE_BUF 時, Linux 將不再保證其寫入的原子性.
???? (4) 注意匿名管道對應的兩個進程之間一定是由血緣關系的
7. 管道特點
???? (1) 管道具有單向性
???? (2) 有血緣關系的進程之間才能進行通信(匿名管道)
???? (3) 管道必須滿足同步互斥關系(管道沒有數據時,讀端進程將會不讀,阻塞等待, 當管道已經滿的時候就不能對管道進行寫了)
???? (4) 管道的生命周期隨進程
???? (5) 管道提供字節流服務(從管道中一次讀多少由操作系統決定, 即一次讀寫多少不確定)
8. 相關的幾個概念
???? (1) 數據不一致: 一個進程的讀寫影響到另外一個進程的讀寫
???? (2) 臨界資源: 兩個進程看到的一份公共資源,并且一次只允許一個進程使用
???? (3) 臨界區: 進程訪問臨界資源的那段代碼就叫做臨界資源
???? (4) 互斥: 各進程有時需要共享資源, 而且有些資源需要互斥訪問, 因此進程之間競爭使用這些資源, 進程之間的這種關系叫做互斥
???? (5) 進程訪問資源的原子性: 進程在操作某些資源時要不做完, 要不不做, 中間不會收到如何其他進程的干擾.
???? (6) 同步: 進程之間以一種比較安全的順序訪問資源, 這種安全機制就叫做同步
???? (7) 管道自帶同步互斥機制, 當管道中沒有數據時父進程會等待子進程的退出