博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux进程篇 (三) 进程间的通信1 管道通信
阅读量:4687 次
发布时间:2019-06-09

本文共 4177 字,大约阅读时间需要 13 分钟。

通信方式分4大类:

管道通信:无名管道 有名管道
信号通信:发送 接收 和 处理
IPC通信:共享内存 消息队列 信号灯
socke 网络通信

用户空间      进程A     <----无法通信---->      进程B-----------------|--------------------------------------|--------------                 |                                |内核空间          |<------------->  对象 <--------------->|    ----------------------------------------------------------------------//基于文件IO的思想//open    打开或者创建一个文件,内核开辟一个buffer -->打开对象//write    往buffer里面写//read    从buffer读//close    释放buffer

 

1. 进程间的管道通信

用户空间       进程A       <----无法通信---->       进程B-----------------|--------------------------------------|--------------              |                               |内核空间        |<------------->  管道 <--------------->|    ----------------------------------------------------------------------管道文件时一个特殊的文件,由队列来实现open --> pipe管道中的东西读完了,就删除了、管道中如果没有东西可读,就会 读堵塞管道中如果写满了,就会写阻塞

 

1.1 无名管道

无名管道用于父子进程带有亲缘关系的进程

#include 
int pipe(int fildes[2]); //创建//文件描述符 filds[0]-read--出队 filds[1]-write--入队write(); //写read(); //读close(fd[0]);close(fd[1]);------------------------------fd[1]write fd[0]read------------------------------

小例子

int main(){    int fd[2];    //pipe的2个文件描述符    int ret;    ret = pipe(fd);    //创建管道    if(ret < 0){        perror("pipe");        return -1;    }    printf("fd[0] = %d, fd[1] = %d\n",fd[0],fd[1]);    return 0;}
#include 
#include
#include
int main(int argc, char const *argv[]){ int fd[2]; int ret; const char *writebuf = "hello pipe"; char readbuf[1024] = {
0}; //1,创建pipe ret = pipe(fd); if(ret < 0) { perror("pipe"); return -1; } printf("fd[0] = %d,fd[1] = %d\n",fd[0],fd[1]); //2.write ret = write(fd[1],writebuf,strlen(writebuf)); if(ret < 0){ perror("write"); } //2.read ret = read(fd[0],readbuf,1024); if(ret < 0){ perror("read"); return -1; } printf("read: %s\n",readbuf); //3.close close(fd[0]); close(fd[1]); return 0;}

 

1.2 有名管道

  对于无名管道,pipe要在fork之前创建,这样fork的时候,会将fd[0]和fd[1]拷贝,这样两个进程就使用的是同2个设备描述符,如果pipe在fork之后创建,那个2个进程就会分别创建1个管道,操作的不是同一个管道文件,就没办法实行通信。

   也就是说,无名管道只能用于fork创建这样的父子进程, 如果无亲缘关系的进程,无名管道没办法进行通信,就只能使用有名管道。

  有名管道 即创建一个带有文件inode节点的管道文件 p, 该文件不占有内存空间,仅有一个文件节点, 当该节点被open时,才占用内存空间。

   mkfifo 只是在用户空间创建了一个管道文件,并非在内存空间创建管道,只有在open时,才在内存空间创建一个管道。

   注,有名管道两端成对打开时才会开始执行

#include 
#include
int mkfifo(const char *path, mode_t mode); //文件路径 文件权限

 

#include 
#include
#include
#include
int main(int argc, char const *argv[]){ int ret; //0=ok -1=failes ret = mkfifo("./fifo",0755); //创建管道文件 路径+权限 if(ret < 0){ perror("mkfifo"); return -1; } return 0;}

例子

fifo.c 创建有名管道文件

lude 
#include
#include
#include
int main(int argc, char const *argv[]){ int ret; ret = mkfifo("./fifo",0755); //创建管道文件 路径+权限 if(ret < 0){ perror("mkfifo"); return -1; } return 0;}

 

first.c 进程1

#include 
#include
#include
#include
int main(int argc, char const *argv[]){ int fd; int process_int = 0; fd = open("./fifo",O_WRONLY); //注,有名管道两端成对打开时才会开始执行 if(fd < 0){ perror("open"); return -1; } puts("fifo open success."); for(int i=0;i<5;i++){ puts("我是第一个进程"); } sleep(5); process_int = 1; write(fd,&process_int,1); while(1); return 0;}

 

second.c 进程2

#include 
#include
#include
#include
int main(int argc, char const *argv[]){ int fd; int process_int = 0; fd = open("./fifo",O_RDONLY); //注,有名管道两端成对打开时才会开始执行 if(fd < 0){ perror("open"); return -1; } puts("fifo open success."); read(fd,&process_int,1); while(process_int == 0); for(int i=0;i<5;i++){ puts("我是第二个进程"); } while(1); return 0;}

 

转载于:https://www.cnblogs.com/kmist/p/10635823.html

你可能感兴趣的文章
字节流的示例代码
查看>>
类似于抽奖活动的小程序
查看>>
使用终端shell命令批量改动一个文件下的全部文件的读写权限
查看>>
Mysql net start mysql启动,提示发生系统错误 5 拒绝訪问 解决之道
查看>>
MyBatis+MySQL 返回插入的主键ID
查看>>
常见批处理作业调度算法
查看>>
python安装(不影响系统自带python)
查看>>
OpenCV Show Image cvShowImage() 使用方法
查看>>
[CareerCup] 7.6 The Line Passes the Most Number of Points 经过最多点的直线
查看>>
[LeetCode] Parse Lisp Expression 解析Lisp表达式
查看>>
HTML5微数据学习笔记
查看>>
数据结构之-冒泡排序
查看>>
【基础练习】【区间DP】codevs1090 加分二叉树题解
查看>>
HTML5:web socket 和 web worker
查看>>
[转载]从零开始学习OpenGL ES之五 – 材质
查看>>
mobiscroll手机端插件 好用(时间、日历、颜色)
查看>>
利用vertical-align:middle实现在整个页面居中
查看>>
★★停止动画和停止所有动画$(selector).stop() 详解
查看>>
160429、nodejs--Socket.IO即时通讯
查看>>
Poj2826 An Easy Problem
查看>>