首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux进程间通信之管道

Linux进程间通信之管道

作者头像
xcywt
发布2018-01-11 16:35:00
2.5K0
发布2018-01-11 16:35:00
举报
文章被收录于专栏:xcywtxcywtxcywt

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;
}

运行效果如下:

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

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;
}

运行效果如下:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-01-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档