管道分为有名管道、匿名管道
1.匿名管道
匿名管道用于具有亲缘关系中通信,只能单向传输(单工),由系统提供一块内存空间
系统提供函数如下:
int pipe(int pipefd[2]);
功能:创建一个匿名管道
参数:pipefd 用于返回两个文件描述符,这两个描述符分别指向管道的读端和写端。pipefd[0]读端,pipefd[1]写端
返回值:
0 成功
-1 错误 errno 被设置
使用管道实现两个管道间的通信:
1.父进程创建管道
2.父进程创建管道(子进程继承父进程的文件描述符)
3.父进程负责的工作
3.1关闭管道的读端
3.2通过管道的写端文件描述符,写数据到管道空间
3.3阻塞等待子进程结束,在子进程结束时收尸
4.子进程负责的工作
4.1关闭文件的写端
4.2通过管道的读端文件描述符,从管道空间读取数据
4.3将读取的数据显示到屏幕上
4.4结束子进程
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
int pipefd[2];
int ret = pipe(pipefd);
if (-1 == ret)
{
perror("pipe");
return -1;
}
pid_t pid = fork();
if (-1 == pid)
{
perror("fork");
return -2;
}
if (pid == 0)
{
char msg[256] = {0};
close(pipefd[1]);
int ret = read(pipefd[0], msg, sizeof(msg));
write(1, msg, ret);
exit(0);
}
//父进程
else
{
char *msg = "this is a test\n";
close(pipefd[0]);
write(pipefd[1], msg, strlen(msg));
wait(NULL);
}
return 0;
}
2.有名管道
有名管道其实是一个文件,这个文件只用于两个进程间通信的桥梁,不存储任何数据内容。
系统提供函数:
int mkfifo(char *pathname, mode_t mode);
功能:创建一个有名管道文件
参数:pathname指定了有名管道的文件名称,mode 指定了管道文件的权限 mode & ~mask
返回值:
0 成功
-1 错误 errno 被设置
创建有名管道文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
if (argc < 2)
{
printf ("argument is not enough\n");
return -1;
}
int mf = mkfifo (argv[1], 0664);
if ( -1 == mf )
{
perror("mkfifo");
return -1;
}
return 0;
}
管道的写端
int main (int argc, char *argv[])
{
char *mp = "this is a test\n";
if (argc < 2)
{
printf ("the argument is not enough\n");
return -1;
}
int fd = open (argv[1], O_WRONLY);
if ( -1 == fd )
{
perror ("open");
return -1;
}
write (fd, mp, strlen (mp));
close ( fd );
return 0;
}
管道的读端
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
if (argc < 2)
{
printf ("argument is not enough\n");
return -1;
}
int fd = open (argv[1], O_RDONLY);
if (-1 == fd)
{
perror ("open");
return -1;
}
char temp[256] = {0};
int size = 0;
size = read (fd, temp, sizeof(temp));
write (1, temp, size);
close (fd);
return 0;
}