Linux进程间通信之管道

简介: 1,进程间通信 (IPC ) Inter-Process Communication   比较好理解概念的就是进程间通信就是在不同进程之间传播或交换信息。   2,linux下IPC机制的分类:管道、信号、共享内存、消息队列、信号量、套接字   3,这篇主要说说管道:本质是文件,其他理论什么的网上已经有一大堆了,我就只写一点用法吧。

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

运行效果如下:

 

目录
相关文章
|
1天前
|
消息中间件 算法 Linux
【Linux】详解如何利用共享内存实现进程间通信
【Linux】详解如何利用共享内存实现进程间通信
|
1天前
|
Linux
【Linux】命名管道的创建方法&&基于命名管道的两个进程通信的实现
【Linux】命名管道的创建方法&&基于命名管道的两个进程通信的实现
|
1天前
|
Linux
【Linux】匿名管道实现简单进程池
【Linux】匿名管道实现简单进程池
|
1天前
|
Linux
【Linux】进程通信之匿名管道通信
【Linux】进程通信之匿名管道通信
|
1天前
|
存储 Linux Shell
Linux:进程等待 & 进程替换
Linux:进程等待 & 进程替换
27 9
|
1天前
|
存储 Linux C语言
Linux:进程创建 & 进程终止
Linux:进程创建 & 进程终止
23 6
|
1天前
|
存储 安全 Linux
Linux:进程地址空间
Linux:进程地址空间
20 10
|
1天前
|
存储 弹性计算 Linux
Linux:进程调度
Linux:进程调度
19 7
|
1天前
|
NoSQL Linux C语言
Linux:进程状态
Linux:进程状态
19 9
|
1天前
|
存储 Linux Shell
Linux:进程概念
Linux:进程概念
17 8