Linux进程间通信之管道

Posted physique

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux进程间通信之管道相关的知识,希望对你有一定的参考价值。

 

 

1,进程间通信 (IPC ) Inter-Process Communication

  比较好理解概念的就是进程间通信就是在不同进程之间传播或交换信息。

 

2,linux下IPC机制的分类:管道、信号、共享内存、消息队列、信号量、套接字

 

3,这篇主要说说管道:本质是文件,其他理论什么的网上已经有一大堆了,我就只写一点用法吧。

3.1 特点

     1)管道是最古老的IPC,但目前很少使用
     2)以文件做交互的媒介,管道分为有名管道和无名管道
     3)历史上的管道通常是指半双工管道

 

3.2 管道:有两种形式,命令行和非命令行

(1)命令行:

        mkfifo testfifo
        echo "testfifo" >fifo
        cat fifo

(2)非命令行:这里又分有名管道无名管道

编程模型:进程A创建管道(mkfifo) -> 进程A写打开管道(open) -> 进程B读打开管道(open) -> 进程A开始往管道里写数据(write) ->

       进程B从管道中读数据(read) -> 进程A关闭管道(close) -> 进程B关闭管道(close) -> 删除管道(unlink)

有名管道(实例):

进程A:

复制代码
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>

#define PIPENAME "pipetest"

int main()
{
    // 创建管道
    if(mkfifo(PIPENAME, 0666) < 0)
    {
        perror("mkfifo");
        return -1;
    }

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

    unlink(PIPENAME);

    int i = 0;
    for(i = 0; i < 10; i++)
    {
        write(fd, &i, sizeof(i));
        printf("%d\\n", i);
        sleep(1); // 这个是以秒为单位挂起
    }

    // 关闭管道
    close(fd);

    return 0;

}
复制代码

进程B:

复制代码
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>

#define PIPENAME "pipetest"

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

    int num = 0;
    int i = 0;
    for(i = 0; i < 10; i++)
    {
        read(fd, &num, sizeof(int));
        printf("%d\\n", num);
        fflush(stdout); // 强制刷新输出缓冲区
    }

    printf("\\n");
    close(fd);

    return 0;

}
复制代码

运行效果如下:

开另外一个终端,运行读进程

 

无名管道:适用于父子进程之间的通信
     int pipe(int pipefd[2]):该函数在内核中创建管道文件,通过输出参数pipefd返回两个文件描述符,其中pipefd[0]用于读pipefd[1]用于写

注意:

  写数据的进程关闭读端pipefd[0]
      读数据的进程关闭写端pipefd[1]
实例:

复制代码
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>

int main()
{
    int fd[2]; // 用来保存文件描述符
    pipe(fd);

    pid_t pid = fork();// 创建进程
    if(pid > 0)
    {
        // 父进程写管道,需要关闭读端
        close(fd[0]);
        int i = 0;
        for(i=10; i<20; i++)
        {
            write(fd[1], &i, sizeof(int));
            sleep(1);
        }

        close(fd[1]);// 关闭写端
        exit(0);
    }

    // 子进程读管道
    close(fd[1]); // 先关闭写端 
    int x;
    int i = 0;
    for(; i<10; i++)
    {
        read(fd[0], &x, sizeof(int));
        printf("%d ", x);
        setbuf(stdout, NULL);
    }
    close(fd[0]);
    printf("\\n");

    return 0;
}
复制代码

运行效果如下:

以上是关于Linux进程间通信之管道的主要内容,如果未能解决你的问题,请参考以下文章

Linux之进程间通信

Linux进程通信之匿名管道

linux之进程间通信——管道

简述Linux进程间通信之管道pipe(下)

Linux之------进程间通信

Linux进程间通信之管道