进程间通信(IPC)
想要用无名管道,得是父子进程或同一个父进程的兄弟进程
有名管道
数据先进先出
输出重定向到管道,输入hello,cat从管道读取hello,完成两个bash进程的通信
管道文件大小还是为0
写入,不读时管道文件大小也是0
管道文件只有i节点,没有数据块,而ls -l查看的是数据块的大小
有名管道的本质是内核维护的一块存储区,A写入,B读走,与磁盘的数据块没有关系
但是内存地址不能告诉用户,防止内核数据泄露,所以将该块存储区与文件系统挂钩,伪造成一种特殊文件,通过文件名找到的不是磁盘的数据块,而是内存的存储区
通过ulimit -a查看该存储区大小,为512 bytes*8 4096 为一页
mkfifo函数
scanf() hello\n 把hello存入指定存储区,\n存入输入缓冲区
fgets() hello\n 把hello\n一起存入存储区
vi wfifo.c 写入数据
vi rfifo.c 读出数据
read函数为阻塞函数,write向管道文件写数据时,read会阻塞等待读取管道文件数据
write写完数据,close管道文件后,管道堵死,read读不到数据返回0,表示对方关闭管道
运行wfifo
运行rfifo后,wfifo显示发送数据
发送数据
输入"!"跳出循环,父进程关闭管道
无名管道
无名管道不通过文件系统找内存地址,而是通过2个文件描述符,1个代表管道的一端
int pipe(int pipefd[2]);int pipefd[2]为输出型参数,是一个数组,存放2个文件描述符
int fd[2];
pipe(fd);
fd[0]读端,fd[1]写端
只有子进程才能继承父进程的文件描述符表,才能用到无名管道
若将父进程关闭读端,子进程关闭写端放在循环之后,即通信时父子进程同时开启读写端,读写端被双重占用
仍然可以传输数据,但是问题出现在关闭时
父进程关闭读写端,子进程占用读写端,写端没关闭,子进程阻塞在read函数,父进程阻塞在回收子进程wait
主要原因是子进程自己留了写端导致子进程无法结束,父进程在哪关影响貌似不大
特殊情况
管道符号
ls -l /etc | more:分屏,ls将数据传给more
ifconfig | grep inet:从ifconfig筛选inet相关的数据
ifconfig | grep inet在bash下输入,ifconfig/grep为2个子进程
bash创建两个新进程A/B,A创建无名管道
将写端描述符复制到A的1,1不再对应显示器而是对应写端,进程A所有printf输出的内容都往写端走
将读端描述符复制到B的0,0不再对应键盘而是对应读端
A变身成ifconfig,输出的内容到管道写端,B变身成gret,读的所有东西从管道读端读
将2个进程通过管道连接起来