Linux 进程间通信之管道

进程之间的通讯之管道

目录

1.无名管道

2.有名管道

3.管道读写规则

1 无名管道


   管道是一种最基本的IPC机制,作用于父子进程之间,完成数据传递。
管道有以下特性:
1.其本质是一个伪文件(实为内核缓冲区)其本质是一个伪文件(实为内核缓冲区)
2.由两个文件描述符引用,一个表示读端,一个表示写端。
3.规定数据从管道的写端流入管道,从读端流出。
3.规定数据从管道的写端流入管道,从读端流出。
管道的原理: 管道实为内核使用环形队列机制,借助内核缓冲区(4k)实现。
无名管道的简单实现:


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main()
{
    int pipefd[2];
    pid_t pid;
    if (pipe(pipefd) == -1 )    
    {
        printf("pipe() err..\n");   
        return -1;
    }
    pid = fork();
    if (pid == -1)
    {
        printf("fork err..\n");
        return -1;
    }

    if (pid == 0)
    {
        close(pipefd[0]);
        write(pipefd[1], "hello hello....", 6);
        close(pipefd[1]);
        printf("child .....quit\n");

    } 
    else if (pid > 0 )
    {
        int len = 0; 
        char buf[100] = {0};
        close(pipefd[1]);
        len = read(pipefd[0], buf, 100);
        printf("len:%d, buf:%s \n", len , buf);

        close(pipefd[0]);
    }
    wait(NULL);
    printf("parent ..quit\n");
    return 0;
}

2.有名管道

命名管道也被称为FIFO文件,是一种特殊的文件。由于linux所有的事物都可以被视为文件,所以对命名管道的使用也就变得与文件操作非常统一。
有名管道实例
1.建立管道C语言实现 或者 shell指令 : mkfifo 文件名
C语言实现

#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 

/*
利用管道,两个进程间进行文件复制。
fifow
读文件1.txt    
    写入管道
fifor   
    读管道
    写入2.txt文件
    */

int main(int argc, char *argv[])
{
    //建立管道文件
    int outfd = 0;

    //打开管道文件,准备写数据
    outfd = open("fifop", O_WRONLY | O_NONBLOCK);
    //outfd = open("pp", O_WRONLY ); //阻塞模式
    if (outfd == -1)
    {
        printf("infd open() err..\n");
        exit(0);
    }

    return 0;
}

写端

#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 

/*
利用管道,两个进程间进行文件复制。
fifow
读文件1.txt    
    写入管道
fifor   
    读管道
    写入2.txt文件
    */

int main(int argc, char *argv[])
{
    //建立管道文件
    mkfifo("fifop", 0644);
    int infd;

    //按只读方式 打开现有文件
    infd = open("./1.txt", O_RDONLY);
    if (infd == -1)
    {
        printf("infd open() err..\n");
        exit(0);
    }
    int outfd;

    //打开管道文件,准备写数据
    //outfd = open("fifop", O_WRONLY | O_NONBLOCK);
    outfd = open("fifop", O_WRONLY ); //阻塞模式
    if (outfd == -1)
    {
        printf("infd open() err..\n");
        exit(0);
    }

    char buf[1024];
    int n = 0;
    //从文件中读数据写入管道文件
    while ( (n = read(infd, buf, 1024)) > 0)
    {
        write(outfd, buf, n);   
    }
    close (infd);
    close (outfd);


    printf("fifow 写管道文件 success\n");
    return 0;
}

读端

#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 



int main(int argc, char *argv[])
{   
    //打开2.txt 准备写数据
    int outfd;
    outfd = open("./2.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); //O_TRUNC 打开文件清空
    if (outfd == -1)
    {
        printf("open()  2.txt err..\n");
        exit(0);
    }


    //打开管道文件,准读数据
    int infd;
    infd = open("fifop", O_RDONLY);
    if (infd == -1)
    {
        printf("open err ... \n");
        exit(0);
    }

    char buf[1024];
    int n = 0;
    //从文件中读数据写入管道文件
    while ( (n = read(infd, buf, 1024)) > 0)
    {
        write(outfd, buf, n);   
    }
    printf("读管道文件是否失败。。。。\n");
    close (infd);
    close (outfd);
    unlink("fifop");


    printf("fifor 读管道文件 success\n");
    return 0;
}

3.管道读写规则

当没有数据可读时
O_NONBLOCK disable:read调用阻塞,即进程暂停执行,一直等到有数据来到为止。
O_NONBLOCK enable:read调用返回-1,errno值为EAGAIN。
当管道满的时候

O_NONBLOCK disable: write调用阻塞,直到有进程读走数据
O_NONBLOCK enable:调用返回-1,errno值为EAGAIN
如果所有管道写端对应的文件描述符被关闭,则read返回0

如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE

当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。

当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。

你可能感兴趣的:(Linux,树莓派学习笔记)