1.思维导图
注意:
管道都是单向传递数据的。
匿名管道:
- filedes[0]用于读出数据,读取时必须关闭写入端,即close(filedes[1]);
filedes[1]用于写入数据,写入时必须关闭读取端,即close(filedes[0])。
命名管道:
打开FIFO文件通常有几种方式:
open(const char *path, O_RDONLY);
open(const char *path, O_RDONLY | O_NONBLOCK);
open(const char *path, O_WRONLY);
open(const char *path, O_WRONLY | O_NONBLOCK);
O_NONBLOCK:open调用是非阻塞的;否则,open调用是阻塞的。
对于以只读方式(O_RDONLY)打开的FIFO文件,如果open调用是阻塞的(即第二个参数为O_RDONLY),除非有一个进程以写方式打开同一个FIFO,否则它不会返回;如果open调用是非阻塞的的(即第二个参数为O_RDONLY | O_NONBLOCK),则即使没有其他进程以写方式打开同一个FIFO文件,open调用将成功并立即返回。
对于以只写方式(O_WRONLY)打开的FIFO文件,如果open调用是阻塞的(即第二个参数为O_WRONLY),open调用将被阻塞,直到有一个进程以只读方式打开同一个FIFO文件为止;如果open调用是非阻塞的(即第二个参数为O_WRONLY | O_NONBLOCK),open总会立即返回,但如果没有其他进程以只读方式打开同一个FIFO文件,open调用将返回-1,并且FIFO也不会被打开。
2.匿名管道实例:
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<sys/wait.h>
int main()
{
//创建一个保存管道的数组,并创建匿名管道
int my_pipe[2];
int ret = pipe(my_pipe);
if (ret == -1) {
printf("creare pipe error\n");
return -1;
}
pid_t id = fork();
if (id < 0) {
printf("fork error\n");
return -1;
}
if (id == 0) {
//关闭子进程读端
close(my_pipe[0]);
int i = 0;
char* mesg_c = NULL;
while (i++ < 10) {
mesg_c = "i am a child!";
write(my_pipe[1],mesg_c,strlen(mesg_c)+1);
sleep(1);
}
close(my_pipe[1]);
} else {
//关闭父进程写端
close(my_pipe[1]);
char _mesg[100];
int j = 0;
while (j++ < 100) {
memset(_mesg,'\0',sizeof(_mesg));
int ret = read(my_pipe[0],_mesg,sizeof(_mesg));
printf("%s:code is :%d\n",_mesg,ret);
}
if (waitpid(id,NULL,0) < 0)
return -1;
}
return 0;
}
3.命名管道实例:
/*命名管道写进程*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#define PATH "./myfifo"
#define SIZE 100
int main()
{
char buf[SIZ_];
memset(buf, '\0', sizeof(buf));
//创建命名管道
int ret = mkfifo(PATH, 0666|S_IFIFO);
if (ret == -1) {
perror("mkfifo error!");
return 1;
}
int fd = open(PATH, O_WRONLY);
if (fd<0) {
printf("open file error!\n");
return 2;
}
while (1) {
read(0, buf, sizeof(buf));
int ret = write(fd, buf, strlen(buf)-1);
buf[ret] = '\0';
if (ret < 0) {
printf("wirte error!\n");
break;
}
if(strncmp(buf, "quit", 4) == 0) {
break;
}
}
close(fd);
return 0;
}
/*命名管道读进程*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#define PATH "./myfifo"
#define SIZE 100
int main()
{
char buf[_SIZE_];
memset(buf, '\0', sizeof(buf));
int fd = open(PATH, O_RDONLY);
if (fd < 0) {
printf("open file error!\n");
return 1;
}
while (1) {
int ret = read(fd, buf, sizeof(buf));
if (ret <= 0) {
printf("read end or error!\n");
break;
}
printf("%s\n", buf);
if (strncmp(buf, "quit", 4)==0) {
break;
}
}
close(fd);
return 0;
}