首页 > 系统相关 >IO进程间通信-无名管道、有名管道

IO进程间通信-无名管道、有名管道

时间:2024-07-04 19:27:17浏览次数:15  
标签:文件 int 阻塞 间通信 管道 fd IO 打开

1.无名管道

1.1特点

(1)只能用于具有亲缘关系的进程之间的通信

(2)半双工的通信模式,具有固定的读端fd[0]和写端fd[1].

(3)管道可以看成是一种特殊的文件,对于他的读写可以使用文件IO,如read,write。

(4)管道是基于文件描述符的通信方式。当一个管道建立时,他会创建两个描述符fd[0],fd[1],其中fd[0]固定用于读管道,而fd[1]固定用于写管道。

1.2函数接口

int pipe( int fd[2])

功能:创建无名管道

参数:文件描述符 fd[0]:读端 fd[1]:写端

返回值:成功 0

                失败 -1

#include <unistd.h>
#include <stdio.h>

int main(int argc, char const *argv[])
{
    // fd[0] 代表读端 ,fd[1]代表写端
    int fd[2] = {0};

    char buf[65536] = "";
    // 创建无名管道
    int n = pipe(fd);
    // 判断无名管道是否创建成功
    // 若成功,返回值为0;失败,返回值为 -1
    if (n < 0)
    {
        perror(" pipe error");
        return -1;
    }
    // 查看管道读写端的文件描述符
    printf("fd[0]:%d fd[1]:%d \n", fd[0], fd[1]);
    // 通过fd[1]端向管道中写
    write(fd[1], "hello world", 11);
    // 通过fd[0]端从管道中读
    read(fd[0], buf, 11);
    printf("%s \n", buf);

    return 0;
}

1.3注意事项

(1)当管道中无数据,读操作会阻塞。

        当管道中有数据,关闭写端,可以将数据读出

        当管道中无数据,关闭写端,读操作会立即返回

(2)管道中写满(管道大小64k)再写数据会阻塞,只有用大于4k空间之后,才可以继续写数据

(3)只有当管道读端存在时,向管道中写数据才有意义,否则会导致管道破裂。向管道中写入数据昵称会收到来自内核的SIGPIPE信号(通常是broke pipe 错误)。

2.有名管道

2.1特点

(1)有名管道可以使互不相关的两个进程互相通信
(2)有名管道可以通过路径名来指出,并且在文件系统中可见,但内容存放在内存中,但是读写数据不会在文件中,而是在管道中。

(3)进程通过文件IO来操作有名管道

(4)有名管道遵循先进先出原则

(5)不支持如lseek()操作

2.2函数接口

int mkfifo( constchar *filename, mode_t mode);

功能:创健有名管道

参数:filename:有名管道文件名

        mode:权限

返回值:成功:0

        失败:-1,并设置errno号

注意对错误的处理方式:

如果错误是file exist时,注意加判断,如:if(errno == EEXIST)

注:函数只是在路径下创建管道文件,往管道中写的数据依然写在内核空间。

先创建有名管道,然后用文件IO操作:打开、读写和关闭。

2.3注意事项

(1)只写方式打开,阻塞,一直到另一个进程把读打开

(2)只读方式打开,阻塞,一直到另一个进程把写打开

(3)可读可写,如果管道中没有数据,读阻塞。

// 1. `O_RDONLY`:只写方式打开阻塞。这表示该文件描述符以只读方式被打开,
// 如果尝试写入数据到该管道,会一直阻塞,直到另一个进程使用写方式打开该管道。

// 2. `O_WRONLY`:只读方式打开阻塞。这表示该文件描述符以只写方式被打开,
// 如果尝试从该管道读取数据,会一直阻塞,直到另一个进程使用读方式打开该管道。

// 3. `O_RDWR`:可读可写。
// 如果管道中没有数据可读,读取操作会阻塞,直到有数据可读;
// 如果管道已满,写入操作也会阻塞,直到有足够的空间可写。

2.4读写示例

#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>

int main(int argc, char const *argv[])
{
    int fd;
    char buf[32] = "";

    // 创建管道文件
    int n;
    n = mkfifo("fifo", 0666);
    // 判断管道文件是否创建成功
    if (n < 0)
    {
        // 如果错误号errno为EEXIST则代表管道文件已存在
        // 如果管道文件已存在,则打印句提示语句而不是走到return -1
        if (errno == EEXIST)
        {
            printf("file exist\n");
        }
        else
        {
            perror("mkfifo err");
            return -1;
        }
    }
    printf("mkfifo success\n");

    // 打开管道文件
    fd = open("fifo", O_RDWR);

    if (fd < 0)
    {
        perror("fifo open error");
        return -1;
    }
    printf("fd = %d \n", fd);

    // 读写操作
    write(fd, "hello", 5);
    read(fd, buf, 32);
    printf("%s \n", buf);

    return 0;
}

3.无名管道和有名管道的区别

无名管道

有名管道

使用场景

只能用于具有亲缘关系的进程之间的通信

不相干的两个进程也可以

特点

半双工的通信模式

具有固定的读端fd[0]和写端fd[1]。

通过文件IO操作

管道是基于文件描述符的通信方式。

在文件系统中会存在管道文件,但是数据放在内核空间

通过文件IO进行操作

遵循先进先出,不支持lseek操作

函数

pipe()

直接read、write

mkfifo()

先打开open,再读写read、write

读写特性

管道中无数据,读阻塞

关闭写端,有数据读出,无数据立即返回

管道写满64k,写阻塞,直到有4k空间才能继续写入

关闭读端,写入会使管道破裂

只写方式打开会阻塞,一直到另一个进程把读方式打开

只读方式打开会苏俄,一直到另一个进程把写方式打开

可读可写,如果管道中无数据读会阻塞

标签:文件,int,阻塞,间通信,管道,fd,IO,打开
From: https://blog.csdn.net/weixin_67273669/article/details/140187165

相关文章

  • 为什么JWT 比 session 更适合于分布式系统
    在分布式系统中,JWT(JSONWebToken)比传统的session更适合用于身份验证和授权,主要有以下几个原因:1.无状态性JWT:无状态:JWT是无状态的,每个JWT包含了所有必要的用户信息和验证数据,服务器不需要存储会话数据。客户端持有JWT,并在每次请求时将其发送给服务器进行验证。扩展性......
  • 基于StableDiffusion3的AI图像生成
        随着人工智能技术的不断进步,图像生成已经成为一个备受关注的领域。StableDiffusion3作为最新一代的图像生成模型,以其卓越的性能和灵活的配置受到了广泛的关注。本文将详细讲解如何配置和使用StableDiffusion3进行AI图像生成。    一、前提条件在开始之前,......
  • Create Operations and the Oracle Restart Configuration
    CreateOperationCreatedComponentAutomaticallyAddedtoOracleRestartConfiguration?CreateadatabasewithOUIorDBCAYesCreateadatabasewiththe CREATE DATABASE SQLstatementNoCreateanOracleASMinstancewithOUI,DBCA,orASM......
  • BIOS和UEFI
    BIOS和UEFI来源:https://www.bilibili.com/video/BV16f4y1U7dw/?vd_source=9eb4bfe03031a37efb5ee2d5c74dba21BIOS(基本输入输出系统)在老旧主板上使用了,界面:蓝底白字,没有图形化界面位于软硬件之间的桥梁开机——BIOS初始化——BIOS自检——引导操作系统MBR(主引导记录),磁盘的......
  • web.py框架下的application.py模块 —— Python
    本文主要分析的是web.py库的application.py这个模块中的代码。总的来说,这个模块主要实现了WSGI兼容的接口,以便应用程序能够被WSGI应用服务器调用。WSGI是WebServerGatewayInterface的缩写,具体细节可以查看WSGI的WIKI页面接口的使用使用web.py自带的HTTPServer下面这个例......
  • iOS-列表视图
    在iOS开发中,UITableView和UICollectionView是两个非常核心的用于展示集合数据的UI组件。它们都能以列表的形式展示数据,但各自的特点和使用场景有所不同。UITableViewUITableView用于展示和管理垂直滚动的单列数据列表。它是以行的形式展示数据,每行(cell)可以展示相同或不同类型的......
  • Stable Diffusion之最全详解图解
    StableDiffusion是一种生成图像模型,属于扩散模型的一种。它利用扩散过程生成图像,从而在图像生成和编辑任务中表现出色。以下是对StableDiffusion的详细解释和图解:概述StableDiffusion是一种基于扩散过程的图像生成模型。扩散过程包括两个主要步骤:正向扩散和逆向扩......
  • 深入探索Java IO与NIO:差异与高性能网络编程的应用
    深入探索JavaIO与NIO:差异与高性能网络编程的应用一、引言在Java中,I/O(Input/Output)操作是应用程序与外部世界交互的基本方式。Java标准库提供了多种I/O模型,其中最常用的有传统的I/O(即阻塞I/O)和新引入的NIO(Non-blockingI/O,非阻塞I/O)。随着网络应用的日益复杂和性能要求的......
  • 【AppStore】一文让你学会IOS应用上架Appstore
    前言咱们国内现在手机分为两类,Android手机与苹果手机,现在用的各类APP,为了手机的使用安全,避免下载到病毒软件,官方都极力推荐使用手机自带的应用商城进行下载,但是国内Android手机品类众多,手机商城各式各样,做不到统一,所以Android的APP上架得一个一个平台去申请上架,一直让开发人员头......
  • 基础篇:Stable Diffusion 基础原理详述
    【基础篇】StableDiffusion基础原理详述前言我认为学习ComfyUI应该先从理论学起。与传统绘图工具(如Photoshop或Figma)相比,AI绘图工具有着显著不同。首先,许多设置和操作在AI绘图工具中是非可视化的,这意味着即使你更改了某个配置,界面上也未必会有任何变化,这使得自学变得更......