无名管道
只能用于具有亲缘关系的进程间通信
无名管道创建后,进程会获得操作管道的两个文件描述符,创建子进程时,子进程会拷贝得到父进程的操作无名管道的两个文件描述符,
函数接口:pipe
pipe
int pipe(int pipefd[2]);
功能:
创建一个用来通信的管道
参数:
pipefd:存放管道两端(读写)的文件描述符数组
成功返回0
失败返回-1
举例:两个进程任务操作同一管道实现通信。(父子进程)
#include "../head.h"
int main()
{
pid_t pid;
char tmpbuff[1024]={0};
int pip[2]={0};
int size=0;
pipe(pip);
pid=fork();
if(pid==-1)
{
return -1;
}
//父进程负责写
if(pid==0)
{
strcpy(tmpbuff,"hello world");
write(pip[1],tmpbuff,strlen(tmpbuff));
}
//子进程负责读
else if(pid>0)
{
size=read(pip[0],tmpbuff,sizeof(tmpbuff));//要是有一个写端,读端一直阻塞等待
printf("tmpbuff=%s,读到的字节数为%d\n",tmpbuff,size);
}
return 0;
}
注意 :
1.如果管道中至少有一个写端:
如果管道中有数据,直接读出
如果管道中没有数据,会阻塞等待直到有数据写入后读出
2.如果管道中没有写端:
如果管道中有数据,直接读出
如果管道中没有数据,不会阻塞直接继续向下执行
3.如果管道中至少有一个读端:
如果管道没有写满,直接写入
如果管道中写满(64k),则阻塞等待,等有数据读出才能继续写入
4.如果管道中没有读端:
向管道中写入数据会产生管道破裂信号
有名管道
通过管道在文件系统中的路径找到管道名,两个进程以读写的方式打开同一管道完成通信
有名管道必须读写两端同时加入后,才能继续向下执行
函数接口: mkfifo
mkfifo
int mkfifo(const char *pathname, mode_t mode);
功能:
创建一个管道
参数:
pathname:管道文件的路径
mode:权限
返回值:
成功返回0
失败返回-1
举例:write.c给管道中写数据
#include "../head.h"
extern int errno;
int main()
{
int fd=0;
int ret=0;
char tmpbuff[1024]={0};
ret=mkfifo("/tmp/myfifo",0664);
if(ret==-1 && errno!=EEXIST)
{
perror("failed to myfifo");
return -1;
}
fd=open("/tmp/myfifo",O_WRONLY);
if(fd==-1)
{
perror("failed to open");
return -1;
}
printf("打开管道成功!\n");
write(fd,"hello world",11);
close(fd);
return 0;
}
read.c从管道中读数据
#include "../head.h"
extern int errno;
int main()
{
int fd=0;
int ret=0;
size_t size=0;
char tmpbuff[1024]={0};
ret=mkfifo("/tmp/myfifo",0664);
if(ret==-1 && errno!=EEXIST)
{
perror("failed to myfifo");
return -1;
}
fd=open("/tmp/myfifo",O_RDONLY);
if(fd==-1)
{
perror("failed to open");
return -1;
}
printf("打开管道成功!\n");
size=read(fd,tmpbuff,sizeof(tmpbuff));
printf("tmpbuff=%s,读到的字节为%ld\n",tmpbuff,size);
close(fd);
return 0;
}