我们知道进程间是可以通信的。可以达到数据传输、资源共享、事件通知、进程控制等目的。进程间通信主要包括管道、系统IPC,套接字等。
管道分为三种:
1、普通管道
int pipe(int fds[2]);//返回值0表示成功,-1表示失败
fd[0]:读 fd[1]:写
子进程往管道中写数据,写数据时要关闭读端
父进程往管道中读数据,写数据时要关闭写端
#include
2 #include
3 #include
4 #include
5
6 int main(void)
7 {
8 int fds[2];
9 if(pipe(fds)==-1)
10 perror("pipe"),exit(1);
11 pid_t pid=fork();
12 if(pid==-1) perror("fork"),exit(1);
13
14 if(pid==0){//子进程
15 close(fds[0]);//关闭读端
16 sleep(1);
17 write(fds[1],"abj",3);//在写端上写入abj
18 close(fds[1]);//再关闭写端
19 exit(0);
20 }else{//父进程
21 close(fds[1]);//关闭写端
22 char buf[100]={};
23 int r=read(fds[0],buf,100);//将管道中的数据读到buf中,返回值是实际读取的字节数
24 if(r==0)//读取的自己为0,代表读取文件结束
25 printf("read EOF\n");
26 else if(r==-1){
27 perror("read"),exit(1);
28 }
29 else if(r>0)
30 printf("buf=[%s]\n",buf);
31 close(fds[0]);//读取成功,关闭读端
32 exit(0);
33 }
34 }
35
2、匿名管道 :
管道的创建
管道文件大小为0,没有情缘关系的文件也能通过管道名,来取到该管道中的缓存。
//创建管道文件
int mkfifo(const char *name,mode_t mode)
//打开管道文件
int fd=open(name,O_RDONLY);读
int fd=open(name,O_WRONLY);写
//read/write,语义和匿名管道一样
利用命名管道实现文件的复制,代码如下:
1)、将文件写入命名管道中
#include
#include
#include
#include
#include
int main(char argc,char *argv[])
{
mkfifo("tp",0644);//创建一个命名管道
int infd=open("abc",O_RDONLY);//表示要复制的文件
if(infd<0)
perror("open"),exit(1);
int outfd=open("tp",O_WRONLY);//写入到管道文件中
if(outfd<0)
perror("open"),exit(1);
char buf[100];
int n=0;
while((n=read(infd,buf,100))>0){
write(outfd,buf,n);//往outfd中写入数据
}
close(infd);
close(outfd);
return 0;
}
2)、将管道中的数据导入到拷贝文件中
#include
#include
#include
#include
#include
int main(int argc,char *argv[])
{
int outfd=open("abc_bk",O_RDONLY|O_WRONLY|O_CREAT|O_TRUNC,0644);//需要拷贝的文件
if(outfd<0)
perror("open"),exit(1);
int infd=open("tp",O_RDONLY);//打开管道,将管道中的数据读走
if(infd<0)
perror("open"),exit(1);
char buf[100];
int n;
while((n=read(infd,buf,100))>0){
write(outfd,buf,n);
}
close(infd);
close(outfd);
unlink("tp");//删除指定名字的文件
return 0;
}
3、匿名管道和命名管道的区别:
匿名管道是由pipe函数创建 并打开的
命名管道是由mkfifo函数创建 的 ,打开用open
命名管道和匿名管道唯一的区别就是在创建的打开,一旦这些工作完成后,它们有相同的意义。