进程间通信方式----管道通信

本文深入探讨了C语言中的管道通信机制,包括无名管道和有名管道的工作原理、使用场景及编程实例。详细讲解了如何利用管道进行父子进程间的通信,以及有名管道如何在非父子进程间通信。

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

进程间通信方式----管道通信

C语言中的管道通信是通过在内核中开辟一块空间,用户通过文件io接口来访问这块空空间实现通信目的。管道的优点是直接访问内存,通信速度较快。缺点是一方面管道属于半双工的通信,即同一进程只能读或者写,无法同时读写同一管道。另一方面管道中的数据只能读一次,无法重复读取。进程通过文件IO来操作管道,但是不能使用lseek()操作。管道分为有名管道(fifo)和无名管道(pipe)

  • 无名管道(pipe)
    无名管道在内核中没有自己的文件名。这决定了它只能用于父子进程间的通信。
    头文件:
    #include <unistd.h>
    函数原型:
    int pipe(int pipefd[2]);
    int pipe2(int pipefd[2], int flags);
    @pipefd:存储创建后管道两端的两个文件描述符pipefd[0]为读端,pipefd[1]为写端。
#include <unistd.h>
#include <stdio.h>
#include <errno.h>

int main()
{
    //创建无名管道
    int fd[2];
    if (-1 == pipe(fd))
    {
        perror("pipe error");
        return 0;
    }

    //创建进程
    int pid = fork();
    if (-1 == pid)
    {
        perror("pid error");
        return 0;
    }
    else if (0 == pid)
    {
        //子进程
        close(fd[0]);//关闭读端
        char buf[10] = "hello!";
        write(fd[1], buf, 10);
    }
    else
    {
        //父进程
        sleep(1);//确保管道信息已写入
        close(fd[1]);//关闭写端
        char buf[10] = {0};
        read(fd[0], buf, 10);
        printf("%s\n", buf);
    }

	//等待程序结果输出完毕退出程序
    sleep(2);
    return 0;
}

管道在默认情况(没有设置O_NONBLOCK)下属于阻塞读写
注意:
1)所有写端都关闭,仅有读端描述符时,读端读取数据,read返回0
2)所有读端都关闭,写端写入数据,进程将收到SIGPIPE信号,程序崩溃
3)写端不再写入数据,读端将管道数据读取完毕后再读取会阻塞
4)读端不再读取数据,写端还在写入数据到管道,管道空间满后,继续写入数据会阻塞

  • 有名管道
    有名管道可以通过路径名来指出,并且在文件系统中可见,但内容存放在内存中。所以有名管道可以在非父子管道之接进行通信。
    头文件:
    #include <sys/types.h>
    #include <sys/stat.h>
    函数原型:
    int mkfifo(const char *pathname, mode_t mode);
    @pathname:带路径的文件名,表示要创建的管道
    @mode:权限(可以使用0666(读写权限)这种写法)

fifowrite.c

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define FIFO_PATH "/home/abing/test.fifo"

int main()
{
    //创建管道
    if (-1 == mkfifo(FIFO_PATH, 0666) && errno != EEXIST)
    {
        perror("mkfifo error");
        return 0;
    }

    //打开管道
    int fd = open(FIFO_PATH, O_WRONLY);
    if (-1 == fd)
    {
        perror("open error");
        return -1;
    }

    //写入数据
    write(fd, "hello!", 7);

    close(fd);
    return 0;
}

fiforead.c

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define FIFO_PATH "/home/abing/test.fifo"

int main()
{
    //打开管道
    int fd = open(FIFO_PATH, O_RDONLY);
    if (-1 == fd)
    {
        perror("open error");
        return -1;
    }

    //读取数据
    char buf[10] = {0};
    read(fd, buf, 7);
    printf("%s\n", buf);

    close(fd);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值