进程间通信(IPC):管道、信号量、共享内存、消息队列、套接字
管道是在内存中实现,不在磁盘中,只作为一个通道,大小为0
通信分为单工、半双工、全双工
单工:a—>b不可逆,一次成型
半双工:a->b或b->a可逆,可以调整方向,但需要重新打开,管道为半双工
全双工:a<–>b 直接表现为可逆
管道的读写也是用 open write read close
open 必须打开至少两个进程(读写) 否则就会阻塞住
也可分为有名管道和无名管道
无名管道:父子进程之间进行
有名管道:任意进程之间 mkfifo 管道名(创建管道)
有名管道
写端:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<fcntl.h>
int main()
{
int fd = open("fifo",O_WRONLY);//打开文件操作
assert(fd!=-1);
while(1)
{
signal(SIGPIPE,SIG_IGN);//如果读端关闭,忽略这个信号,此时写端不会关闭,再打开读端会将写入的数据读到
printf("input:");
char buff[128] = {0};
fgets(buff,128,stdin);//从键盘获取数据
if(strncmp(buff,"end",3)==0)//如果读到exit则退出
{
break;
}
write(fd,buff,strlen(buff));//给管道写入数据
}
close(fd);
exit(0);
}
读端:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<assert.h>
int main()
{
int fd = open("fifo",O_RDONLY);
assert(fd!=-1);
while(1)
{
char buff[128] = {0};
if(read(fd,buff,128)==0)//如果写端没有写数据直接退出则读端也会退出
{
break;
}
printf("%s",buff)
}
close(fd);
exit(0);
}
无名管道
int fd[2]存放读短和写端操作,利用pipe()函数将此变为管道
fd[0]为读操作 fd[1]为写操作
可以将父进程设为读端或者写端
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
int main()
{
int fd[2];
pipe(fd);
pid_t pid = fork();
assert(pid != -1);
if(pid == 0)
{
close(fd[1]);//关闭写端,将子进程设为读端
char buff[128] = {0};
read(fd[0],buff,128);//读操作
printf("%s",buff);
close(fd[0]);//关闭读端
}
else
{
close(fd[0]);//关闭读端,将父进程设为写端
char buff[128] = {0};
printf("input:\n");
fgets(buff,128,stdin);//从键盘读入数据
write(fd[1],buff,strlen(buff));
close(fd[1]);//关闭写端
}
exit(0);
}