进程间通信相关概念
1.什么是IPC ?
即:进程间通信 InterProcess Communication
2.进程间通信常用的4种方式:
a.管道·简单
b.信号.系统统开销小
c.共享映射区·(有无血缘关亲的进程间通信都可以)
d.本地套接字-稳定
匿名管道
本质:内核缓冲区,是伪文件,不占磁盘空间
特点:数据写端流入,读端流出;对应2个文件描述符;操作管道的进程被销毁后管道自动释放,管道默认是阻塞的。
原理:内部实现方式:队列,先进先出。默认4k,大小会根据实际情况适当调整,但不会无限扩大。
局限性:队列一次只能读取一次,不能重复读取。是半双工的。(如对讲机)。适用于有血缘关系的进程。
创建匿名管道 int pipe(int pipefd[2]);
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
int main(int argc,char* argv[])
{
int fd[2];
int ret=pipe(fd);
if(ret==-1)
{
perror("pipe error");
exit(1);
}
printf("pipe[0]=%d\tpipe[1]=%d\n",fd[0],fd[1]);
close(fd[0]);
close(fd[1]);
return 0;
}
root@huislee-virtual-machine:/home/huislee/workspace/workspace/process/communication# ./a
pipe[0]=3 pipe[1]=4
注:0,1,2默认对应标准输出输入和错误。最小的为3,没有被占用就会直接分配,否则依次递增。
注:有血缘关系的进程之间通信fork的位置:
需要父子进程都可以操作管道的读和写,所以创建子进程需要在创建管道之后。
父子间进程通信实现ps aux | grep bash
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
int main(int argc,char* argv[])
{
int fd[2];
int ret=pipe(fd);
if(ret==-1)
{
perror("pipe error");
exit(1);
}
pid_t pid=fork();
if(pid==-1)
{
perror("perror error");
exit(1);
}
//父进程 ps aux
if(pid>0)
{
//写管道操作 需要关闭读端
close(fd[0]);
//文件描述符重定向 标准输出->管道写端
dup2(fd[1],STDOUT_FILENO);
//执行ps aux
execlp("ps","ps","aux",NULL);
perror("execlp");
exit(1);
}
//子进程 grep "bash"
else if(pid==0)
{
close(fd[1]);
dup2(fd[0],STDIN_FILENO);
execlp("grep","grep","--color=auto","bash",NULL);
}
printf("pipe[0]=%d\tpipe[1]=%d\n",fd[0],fd[1]);
close(fd[0]);
close(fd[1]);
return 0;
}
huislee@huislee-virtual-machine:~/workspace/workspace/process/communication$ ./a
huislee 9020 0.0 0.0 24876 1632 pts/0 Ss+ 09:33 0:00 bashroot 9455 0.0 0.0 24796 1604 pts/1 Ss+ 09:36 0:00 -bash
huislee 10882 0.0 0.2 24876 4248 pts/2 Ss 10:20 0:00 /bin/bash
huislee 14622 0.0 0.0 16180 1020 pts/2 S+ 15:56 0:00 grep --color=auto bash
兄弟进程通信实现ps aux | grep bash,父进程进行回收资源
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
int fd[2], i = 0;
int ret = pipe(fd);
if (ret == -1)
{
perror("pipe error");
exit(1);
}
for (i = 0; i < 2; i++)
{
pid_t pid;
pid = fork();
if (pid == 0)
{
break;
}
if (pid == -1)
{
perror("perror error");
exit(1);
}
}
//子进程1 ps aux
if (i == 0)
{
//写管道操作 需要关闭读端
close(fd[0]);
//文件描述符重定向 标准输出->管道写端
dup2(fd[1], STDOUT_FILENO);
//执行ps aux
execlp("ps", "ps", "aux", NULL);
perror("execlp");
exit(1);
}
//子进程2 grep "bash"
else if (i == 1)
{
close(fd[1]);
dup2(fd[0], STDIN_FILENO);
execlp("grep", "grep", "--color=auto", "bash", NULL);
}
else if (i == 2)
{
close(fd[0]);
close(fd[1]);
//回收子进程
pid_t wpid;
while ((wpid = waitpid(-1, NULL, WNOHANG)) != -1)
{
if (wpid == 0)
{
continue;
}
printf("child died pid=%d\n", wpid);
}
}
printf("pipe[0]=%d\tpipe[1]=%d\n", fd[0], fd[1]);
close(fd[0]);
close(fd[1]);
return 0;
}
root@huislee-virtual-machine:/home/huislee/workspace/workspace/process/communication# ./a
huislee 9020 0.0 0.0 24876 1636 pts/0 Ss+ 09:33 0:00 bash
root 9455 0.0 0.1 24796 2640 pts/1 Ss 09:36 0:00 -bash
huislee 10882 0.0 0.2 24876 4248 pts/2 Ss+ 10:20 0:00 /bin/bash
root 14831 0.0 0.0 16180 1132 pts/1 S+ 16:32 0:00 grep --color=auto bash
child died pid=14830
child died pid=14831
pipe[0]=3 pipe[1]=4
查看管道缓冲区大小
命令:ulimit -a 函数:fpathconf
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
int fd[2], i = 0;
int ret = pipe(fd);
if (ret == -1)
{
perror("pipe error");
exit(1);
}
//测试管道默认大小
long size = fpathconf(fd[0], _PC_PIPE_BUF);
printf("size=%ld\n", size);
printf("pipe[0]=%d\tpipe[1]=%d\n", fd[0], fd[1]);
close(fd[0]);
close(fd[1]);
return 0;
}
huislee@huislee-virtual-machine:~/workspace/workspace/process/communication$ ./a
size=4096
pipe[0]=3 pipe[1]=6
huislee@huislee-virtual-machine:~/workspace$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 7705
max locked memory (kbytes, -l) 16384
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8 //512*8为管道大小
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7705
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited