Linux系统编程(三)进程间的通信
Linux系統(tǒng)編程(三)進程間的通信
- 一、為什么需要進程之間的通信(IPC)?
- 二、管道
- 1.概念
- 2.特質
- 3.原理
- 4.局限性
- 5.代碼
- 2.讀入數(shù)據(jù)
- 三、共享存儲映射
- 注意事項
- 父子進程通信
一、為什么需要進程之間的通信(IPC)?
當我們編碼時會發(fā)現(xiàn)我們使用全局變量并不能在父子進程之間使用,這是為什么呢?是因為進程與進程之間是相互獨立,當我們在主進程當中修改那個全局變量的時候,子進程的并不會變,因為兩者用戶空間的那塊地址是不一樣的。這時候我們引入了IPC,它是在內核創(chuàng)建了一個緩沖區(qū),進程通過這個緩沖區(qū)實現(xiàn)進程之間的通信。
二、管道
1.概念
管道是一種最基本的IPC機制,作用于有血緣關系的進程之間,完成數(shù)據(jù)傳遞。調用pipe系統(tǒng)函數(shù)即可創(chuàng)建一個管道。
2.特質
1.管道的本質是一個偽文件,不占用磁盤資源
2.由兩個文件描述符引用,一個表示讀端,一個表示寫段
3.數(shù)據(jù)從管道寫段流入,讀端流出
3.原理
管道內核使用環(huán)形隊列機制,借助內核緩沖區(qū)(4k)實現(xiàn)
4.局限性
1.數(shù)據(jù)不能自己讀自己寫
2.數(shù)據(jù)一旦被讀走,便不在管道中存在,不可重復讀取
3.由于管道采用半雙工通信方式。數(shù)據(jù)只能一個方向上流動
4.只能在由公共祖先的進程間使用管道
5.代碼
代碼如下(示例):
#include <cstdio> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h>int main() {pid_t pid;int fd[2];int ret=pipe(fd);if (ret == -1){perror("pipe error:");exit(1);}pid = fork();if(pid==-1){ perror("pipe error:");exit(1);}else if (pid == 0) //子進程{sleep(1);close(fd[1]);char buf[1024];ret=read(fd[0], buf, sizeof(buf));if (ret == 0){printf("-----------\n");}write(STDOUT_FILENO,buf,ret);}else{close(fd[0]);char* str = "hello";write(fd[1], "hello pipe\n", strlen("hello pipe\n"));wait(NULL);}return 0; }2.讀入數(shù)據(jù)
代碼如下(示例):
data = pd.read_csv('https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv') print(data.head())該處使用的url網絡請求的數(shù)據(jù)。
三、共享存儲映射
注意事項
1.創(chuàng)建映射區(qū)的過程中,隱含著一次對映射文件的讀操作。
2. 當MAP_SHARED時,要求:映射區(qū)的權限應 <=文件打開的權限(出于對映射區(qū)的保護)。而MAP_PRIVATE則無所謂,因為mmap中的權限是對內存的限制。
3. 映射區(qū)的釋放與文件關閉無關。只要映射建立成功,文件可以立即關閉。
4. 特別注意,當映射文件大小為0時,不能創(chuàng)建映射區(qū)。所以:用于映射的文件必須要有實際大小!! mmap使用時常常會出現(xiàn)總線錯誤,通常是由于共享文件存儲空間大小引起的。
5. munmap傳入的地址一定是mmap的返回地址。堅決杜絕指針++操作。
6. 如果文件偏移量必須為4K的整數(shù)倍
7. mmap創(chuàng)建映射區(qū)出錯概率非常高,一定要檢查返回值,確保映射區(qū)建立成功再進行后續(xù)操作。
父子進程通信
```csharp #include <cstdio> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/wait.h>int main() {//實現(xiàn)父子進程之間的通信int* p;int var = 100;pid_t pid;int fd = open("temp",O_CREAT|O_RDWR,0644);if (fd < 0 ){perror("open error:");exit(1);}//unlink("temp");ftruncate(fd,4);p=(int*)mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);if (p == MAP_FAILED){perror("mmap error:");exit(1);}//關閉文件close(fd);//創(chuàng)建子線程pid = fork();if (pid == 0){*p = 2000;var = 1000;printf("child,p = %d,var = %d\n",*p,var);}else if(pid > 0){sleep(1);printf("parent,p = %d,var = %d\n", *p, var);wait(NULL);//釋放映射區(qū)int ret = munmap(p,4);if (ret == -1){perror("munmap error:");exit(1);}}return 0; }總結
以上是生活随笔為你收集整理的Linux系统编程(三)进程间的通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 摩码者剧情介绍
- 下一篇: 使用mmap实现大文件的复制:单进程与多