栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Linux —— 进程间通讯:管道

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux —— 进程间通讯:管道

提示:进程在运行时总是独享其内存镜像,进程间的通讯一般借助管道来完成

文章目录
  • 前言
  • 一、pipe
    • 1. 内容详解
    • 2. 示例代码
  • 二、fifo
    • 1. 内容详解
    • 2. 示例代码
  • 总结


前言

应用程序在运行时所产生的进程,在操作系统的加持下都是独享其整个虚拟内存镜像的,这里的独享举例:
在32位的操作系统下,应用程序运行时候的进程,在其运行周期的时间片上,总是独享CPU和4G的内存空间,一般来说4G中的3G为应用程序使用,剩余的1G是交给操作系统内核来使用的。两个不同的进程,其3G的虚拟内存空间是完全独立的,不能直接共享。

在进程独享虚拟内存的前提下,进程间的通讯,也就是交换数据,就需要通过操作系统内核内存或者文件系统(外部磁盘存储介质)来实现。

在 linux 系统下,提供了 pipe 匿名管道的方式借助系统内核内存用于有父子或兄弟关系的进程间通讯,以及 fifo 管道的方式借助文件系统进行通讯。


一、pipe 1. 内容详解

pipe 的管道文件主要用于有直系关系的进程间通讯,比如:父子进程或兄弟进程,主要依靠 pipe(2) 函数,其原型为:
int pipe(int pipefd[2]);

2. 示例代码
#include 
#include 
#include 
#include 
#include 
#include 

int main(void)
{
    int fd[2];  // fd[0] is read end of pipe, fd[1] is write end of pipe
    pid_t pid;	// for child pid
    char *msg = "father process message";
    char buf[128];

    if (pipe(fd) == -1)
        printf("Error: pipe failedn");

    
 	pid = fork();	// create new child process
    if (pid == -1)
        printf("Error: fork failedn");
    if (pid == 0) { // child process
        printf("child process startedn");
        read(fd[0], buf, 128);
        printf("child process get a message: %sn", buf);
        
        printf("child process deadn");
        
        exit(0);
    }
    else {
        printf("father process startedn");
        write(fd[1], msg, strlen(msg));
        wait(NULL);
    }
    printf("father process finishedn");
    return 0;
}

二、fifo 1. 内容详解

fifo 的管道文件是独立于进程的,用于任意进程间的通讯,主要依靠 mkfifo(3) 函数,其原型为:
int mkfifo(const char *pathname, mode_t mode);

测试代码分为三个部分:
(1)管道文件创建代码
(2)通讯数据写入代码
(3)通讯数据读出代码

三部分代码分别编译之后,先由管道创建程序生成管道文件,至此管道创建程序就不再需要了。
数据写入程序与数据读出程序同时运行时,才能正常的完成通讯并将通讯代码写在屏幕上。如果只打开数据写入/读出代码,都是没办法运行的,因为两方面:
一来是此时的 fifo 文件写入端和读出段都需要打开才能够成功传输数据。
二来是目前的 fifo 配置写入和读出均采用阻塞等待的方式在运行。

2. 示例代码

(1)管道文件的创建:

#include 
#include 
#include 

int main(int argc, char *argv[])
{
    int fd;
    fd = mkfifo(argv[1], 0644);
    if (fd == -1)
        printf("mkfifo failedn");
    else
        printf("create fifo file name %sn", argv[1]);

    return 0;
}

(2)通讯数据写入代码

#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    char *msg = "pwrite msg";
    int size = 0;
    int fd = open(argv[1], O_WRONLY);
    if (fd == -1) {
        printf("open errorn");
        return 0;
    }
    
    size = write(fd, msg, strlen(msg));
    printf("write %d bytes to fifo filen", size);
    close(fd);

    return 0;
}

(3)通讯数据读出代码

#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    char buf[1024] = {0};
    int size = 0;
    int fd = open(argv[1], O_RDONLY);
    if (fd == -1) {
        printf("open errorn");
        return 0;
    }
    
    size = read(fd, buf, 1024);
    printf("read %d bytesn", size);
    printf("%sn", buf);
    close(fd);

    return 0;
}

总结
  1. pipe 和 fifo 的区别在于:pipe提供了匿名管道,自然不会挂载与文件系统,必须有”父子/兄弟”关系的进程才能够生成并进行通讯。fifo提供了和一般文件类似的文件名,将会被挂载至文件系统,可以在任意进程间进行通讯。
  2. 管道文件与普通文件的区别在于:一般情况下管道文件 读/写 两端必须都是打开的状态,才会用于读写操作,基本的读写操作都是阻塞状态。普通文件 读/写 是完全独立的,可以在任意时间操作。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/996875.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号