level 5
西安恩仪联教育
楼主
一、管道概念
1、管道本质是一个有两个描述符文件,一个读端和一个写端
2、通过写端写入数据,通过读端读取数据,具有“先进先出”特点,类似于队列。
3、读管道文件时,文件是空的,则阻塞等待
写管道文件时,如果文件满了,则阻塞
4、分类:
匿名管道:用于亲缘进程之间通信
存在与内存中文件
有名管道:是一个文件,用于任意进程之间通信
二、编程步骤
1、创建管道文件
创建匿名管道
int pipe(int pipefd[2]);
创建有名管道
int mkfifo(const char *pathname, mode_t mode);
2、读写管道采用文件读写函数
读: ssize_t read(int fd, void *buf, size_t count);
写:ssize_t write(int fd, const void *buf, size_t count);
3、关闭:
int close(int fd);
三、编程案例
通过命令mkfifo创建一个有名管道,通过该管道实现进程a给进程b发送一个学员信息。
进程a以写方式打开管道,写入一个学员信息。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
struct student
{
char name[10];
int age;
float score;
};
int main()
{
int ret = 0;
struct student stu;
memset(&stu,0,sizeof(struct student));
strcpy(stu.name,"mike");
stu.age = 23;
stu.score = 78.5;
int fd = 0;
fd = open("./pipe",O_WRONLY);
if(fd == -1)
{
perror("open");
exit(-1);
}
ret = write(fd,&stu,sizeof(struct student));
if(ret == -1)
{
perror("write");
exit(-1);
}
close(fd);
return 0;
}
进程b以读方式打开管道,从其中读取学员信息。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
struct student
{
char name[10];
int age;
float score;
};
int main()
{
int ret = 0;
struct student stu;
memset(&stu,0,sizeof(struct student));
int fd = 0;
fd = open("./pipe",O_RDONLY);
if(fd == -1)
{
perror("open");
exit(-1);
}
ret = read(fd,&stu,sizeof(struct student));
if(ret == -1)
{
perror("write");
exit(-1);
}
printf("name is %s,age is %d,score is %.1f\n",stu.name,stu.age,stu.score);
close(fd);
return 0;
}
四、通过管道通信注意问题:
1、读写管道的函数和读写普通文件的函数是一致的,所以通过管道可以传输任意类型的数据,可以是整型、实型、字符型或者结构体类型,管道按照字节传送,不区分数据类型。
2、读取管道中数据时,如果管道的写端未打开或者管道是空的,则写函数阻塞,给管道中写入数据时,如果读端未打开则写函数阻塞。
3、通过管道通信的过程中,如果写端关闭,则读端解除阻塞立即返回,如果读端关系,则写端立即返回。
2025年12月06日 09点12分
1
1、管道本质是一个有两个描述符文件,一个读端和一个写端
2、通过写端写入数据,通过读端读取数据,具有“先进先出”特点,类似于队列。
3、读管道文件时,文件是空的,则阻塞等待
写管道文件时,如果文件满了,则阻塞
4、分类:
匿名管道:用于亲缘进程之间通信
存在与内存中文件
有名管道:是一个文件,用于任意进程之间通信
二、编程步骤
1、创建管道文件
创建匿名管道
int pipe(int pipefd[2]);
创建有名管道
int mkfifo(const char *pathname, mode_t mode);
2、读写管道采用文件读写函数
读: ssize_t read(int fd, void *buf, size_t count);
写:ssize_t write(int fd, const void *buf, size_t count);
3、关闭:
int close(int fd);
三、编程案例
通过命令mkfifo创建一个有名管道,通过该管道实现进程a给进程b发送一个学员信息。
进程a以写方式打开管道,写入一个学员信息。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
struct student
{
char name[10];
int age;
float score;
};
int main()
{
int ret = 0;
struct student stu;
memset(&stu,0,sizeof(struct student));
strcpy(stu.name,"mike");
stu.age = 23;
stu.score = 78.5;
int fd = 0;
fd = open("./pipe",O_WRONLY);
if(fd == -1)
{
perror("open");
exit(-1);
}
ret = write(fd,&stu,sizeof(struct student));
if(ret == -1)
{
perror("write");
exit(-1);
}
close(fd);
return 0;
}
进程b以读方式打开管道,从其中读取学员信息。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
struct student
{
char name[10];
int age;
float score;
};
int main()
{
int ret = 0;
struct student stu;
memset(&stu,0,sizeof(struct student));
int fd = 0;
fd = open("./pipe",O_RDONLY);
if(fd == -1)
{
perror("open");
exit(-1);
}
ret = read(fd,&stu,sizeof(struct student));
if(ret == -1)
{
perror("write");
exit(-1);
}
printf("name is %s,age is %d,score is %.1f\n",stu.name,stu.age,stu.score);
close(fd);
return 0;
}
四、通过管道通信注意问题:
1、读写管道的函数和读写普通文件的函数是一致的,所以通过管道可以传输任意类型的数据,可以是整型、实型、字符型或者结构体类型,管道按照字节传送,不区分数据类型。
2、读取管道中数据时,如果管道的写端未打开或者管道是空的,则写函数阻塞,给管道中写入数据时,如果读端未打开则写函数阻塞。
3、通过管道通信的过程中,如果写端关闭,则读端解除阻塞立即返回,如果读端关系,则写端立即返回。