第4章 管道与FIFO

本文详细介绍了管道和FIFO的概念及应用,包括管道的基本使用、管道在文件服务器与客户端之间的实现,以及popen和pclose函数的应用。同时,还探讨了FIFO(命名管道)的创建和使用方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4.1 概述

管道只在亲缘进程间使用,FIFO在任意进程间使用

4.2 管道

#include <unistd.h>
int pipe(int fd[2])

fd[0]用来读管道,fd[1]用来写管道

1)命令who | sort | lp中的管道:

2)管道实现文件服务器与客户端:

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <error.h>

#define MAXLINE 1024

void client(int readfd,int writefd);
void server(int readfd,int writefd);

int main()
{
    int fd1[2];
    int fd2[2];
    pipe(fd1);
    pipe(fd2);
    int pid;
    if( (pid = fork()) < 0)
    {
        fprintf(stderr,"fork error\n");
        exit(-1);
    }
    if(pid > 0)
    {
        close(fd1[1]);
        close(fd2[0]);
        server(fd1[0],fd2[1]);
        exit(0);
    }
    close(fd1[0]);
    close(fd2[1]);
    client(fd2[0],fd1[1]);
    waitpid(pid,NULL,0);
    exit(0);
}

void client(int readfd,int writefd)
{
    size_t len;
    char buf[MAXLINE];
    fgets(buf,MAXLINE,stdin);
    len = strlen(buf);
    if(buf[len-1] == '\n')
          --len;
    write(writefd,buf,len);
    while( (len = read(readfd,buf,MAXLINE)) > 0)
          write(STDOUT_FILENO,buf,len);
}

void server(int readfd,int writefd)
{
    char buf[MAXLINE];
    ssize_t n;
    if( (n = read(readfd,buf,MAXLINE)) ==0)
    {
        fprintf(stderr,"error\n");
        exit(-1);
    }
    buf[n] = '\0';
    int fd;
    if( (fd = open(buf,O_RDONLY)) < 0)
    {
        snprintf(buf+n,sizeof(buf)-n,"can't open: %s\n",strerror(errno));
        n = strlen(buf);
        write(writefd,buf,n);
    }
    else
        while( (n = read(fd,buf,MAXLINE)) > 0)
            write(writefd,buf,n);
    close(fd);
}

4.3 popen和pclose函数

#include <stdio.h>
FILE *popen(char *cmd,char *type)
int pclose(FILE *fp)

popen函数创建另外一个进程执行cmd,并在调用进程与创建进程之间建立一个单向管道,管道的一端与返回的FILE对象绑定

type为"w",FILE对象与管道的写端绑定,cmd的标准输入为管道的读端

type为"r",FILE对象与管道的读端绑定,cmd的标准输出为管道的写端

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLINE 1024
int main()
{
        char buf[MAXLINE];
        fgets(buf,MAXLINE,stdin);
        int n = strlen(buf);
        if(buf[n-1] == '\n')
                --n;
        char cmd[MAXLINE];
        snprintf(cmd,MAXLINE,"cat %s",buf);
        FILE *fp = popen(cmd,"r");
        while(fgets(buf,MAXLINE,fp) != NULL)
                fputs(buf,stdout);
        exit(0);
}
View Code

4.4 FIFO

FIFO又称命名管道

#include <sys/stat.h>
#include <sys/types.h>
int mkfifo(char *pathname,mode_t mode)

FIFO实现文件服务器和客户端

#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc,char *argv[])
{
    if(mkfifo("./fifo1",S_IRUSR|S_IWUSR) < 0)
    {
        fprintf(stderr,"mkfifo error\n");
        exit(-1);
    }
    if(mkfifo("./fifo2",S_IRUSR|S_IWUSR) < 0)
    {
        fprintf(stderr,"mkfifo error\n");
        exit(-1);
    }
    int pid;
    if( (pid = fork()) < 0)
    {
        fprintf(stderr,"fork error\n");
        exit(-1);
    }
    if(pid == 0)
    {
        int fd1 = open("./fifo1",O_RDONLY);
        int fd2 = open("./fifo2",O_WRONLY);
        server(fd1,fd2);
        exit(0);
    }
    int fd1 = open("./fifo1",O_WRONLY);
    int fd2 = open("./fifo2",O_RDONLY);
    client(fd2,fd1);
    waitpid(pid,NULL,0);
    exit(0);
}
View Code

4.5 管道、FIFO的阻塞与非阻塞

转载于:https://www.cnblogs.com/buptlyn/p/4178912.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值