基于linux下的高并发服务器开发(第二章)- 2.14 管道的读写特点和管道设置为非阻塞

news2024/12/23 5:51:37

 

管道的读写特点:

使用管道时,需要注意以下几种特殊的情况(假设都是阻塞I/O操作)
1.所有的指向管道写端的文件描述符都关闭了(管道写端引用计数为0),有进程从管道的读端读数据,那么管道中剩余的数据被读取以后,再次read会返回0,就像读到文件末尾一样。

2.如果有指向管道写端的文件描述符没有关闭(管道的写端引用计数大于0),而持有管道写端的进程也没有往管道中写数据,这个时候有进程从管道中读取数据,那么管道中剩余的数据被读取后,再次read会阻塞,直到管道中有数据可以读了才读取数据并返回。

3.如果所有指向管道读端的文件描述符都关闭了(管道的读端引用计数为0),这个时候有进程向管道中写数据,那么该进程会收到一个信号SIGPIPE, 通常会导致进程异常终止。

4.如果有指向管道读端的文件描述符没有关闭(管道的读端引用计数大于0),而持有管道读端的进程也没有从管道中读数据,这时有进程向管道中写数据,那么在管道被写满的时候再次write会阻塞,直到管道中有空位置才能再次写入数据并返回。

总结:
    (1)读管道:
            管道中有数据,read返回实际读到的字节数。
            管道中无数据:
                    写端被全部关闭,read返回0(相当于读到文件的末尾)
                    写端没有完全关闭,read阻塞等待

    (2)写管道:
            管道读端全部被关闭,进程异常终止(进程收到SIGPIPE信号)
            管道读端没有全部关闭:
                    管道已满,write阻塞
                    管道没有满,write将数据写入,并返回实际写入的字节数

noblock.c

#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
/*
    设置管道非阻塞
    int flags = fcntl(fd[0], F_GETFL);  // 获取原来的flag
    flags |= O_NONBLOCK;            // 修改flag的值
    fcntl(fd[0], F_SETFL, flags);   // 设置新的flag
*/
int main() {

    // 在fork之前创建管道
    int pipefd[2];
    int ret = pipe(pipefd);
    if(ret == -1) {
        perror("pipe");
        exit(0);
    }

    // 创建子进程
    pid_t pid = fork();
    if(pid > 0) {
        // 父进程
        printf("i am parent process, pid : %d\n", getpid());

        // 关闭写端
        close(pipefd[1]);
        
        // 从管道的读取端读取数据
        char buf[1024] = {0};

		//把管道的读端设置为非阻塞
        int flags = fcntl(pipefd[0], F_GETFL);  // 获取原来的flag
        flags |= O_NONBLOCK;            // 修改flag的值
        fcntl(pipefd[0], F_SETFL, flags);   // 设置新的flag

        while(1) {
            int len = read(pipefd[0], buf, sizeof(buf));
            printf("len : %d\n", len);
            printf("parent recv : %s, pid : %d\n", buf, getpid());
            memset(buf, 0, 1024);
            sleep(1);
        }

    } else if(pid == 0){
        // 子进程
        printf("i am child process, pid : %d\n", getpid());
        // 关闭读端
        close(pipefd[0]);
        char buf[1024] = {0};
        while(1) {
            // 向管道中写入数据
            char * str = "hello,i am child";
            write(pipefd[1], str, strlen(str));
            sleep(5);
        }
        
    }
    return 0;
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/777724.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot系列--【K8s中的SpringBoot如何给应用配置健康检查?】

K8s中的SpringBoot如何给应用配置健康检查&#xff1f; 1.健康检查的必要性 作为业务监控的首要目标&#xff0c;服务的存活性&#xff0c;也就是它的健康状况&#xff0c;成为了重中之重&#xff0c;容器云平台可以根据健康检查策略来对服务实例进行自动重启或从负载均衡中摘除…

IP-GUARD如何在客户端上进行审批管理?

如何在客户端上进行审批管理&#xff1f; 4 实现步骤如下&#xff1a; 1、先在控制台-加密-加密授权设置-常规中&#xff0c;勾选允许登录审批管理平台开启客户端登录审批管理平台的功能。 2、然后客户端电脑&#xff0c;右键加密托盘登录审批账号后即可正常审批。 如何实现特…

MySQL 8.1.0正式发布!

早在五年前&#xff0c;MySQL 8.0 就发布了第一个 GA 版本&#xff0c;此后一直在这个版本进行更新&#xff0c;而没有升级大版本。最近 MySQL 官方终于发布了 MySQL 8.1.0 和 MySQL 8.0.34&#xff0c;分别代表了创新版和长期支持版。 新版本中与 SQL 相关的改进包括保存执行计…

用C++在Windows桌面上打个叉❌

我们的目标是&#xff0c;只写一二十行代码&#xff0c;用 Windows自带的原生接口&#xff0c;强行在桌面上打个大红❌&#xff0c;如图&#xff1a; 写了大半年C&#xff0c;天天和“黑乎乎” 的小窗口你侬我侬&#xff1f;赶紧来打开一扇“Windows”&#xff0c;从窗口跳进全…

数据库系统课程笔记

初步认识数据库系统 schema 英 /ˈskiːmə/ 美 /ˈskiːmə/ n.(计划或理论的)提要&#xff0c;纲要 关系模型之基本概念 关系和表的差别 关系的特性 什么是sql 创建数据库&#xff08;编写脚本&#xff09; 创建表格语法&#xff08;编写脚本&#xff09; 修改表的结构语法 …

微服务Day4——Docker

一、什么是Docker 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署&#xff0c;环境不一定一致&#xff0c;会…

如何生成一个随机数?

文章目录 虚假的随机数真正的随机数生成规定位数的随机数 虚假的随机数 说到如何生成一个随机数&#xff0c;可能当你百度后会看到这样一段代码。 srand((unsigned int)time(NULL)); int ret rand();那么一个随机数到底是如何生成的呢&#xff1f;我相信善于探索的你一定想知…

(黑客)自学笔记

特别声明&#xff1a; 此教程为纯技术分享&#xff01;本教程的目的决不是为那些怀有不良动机的人提供及技术支持&#xff01;也不承担因为技术被滥用所产生的连带责任&#xff01;本教程的目的在于最大限度地唤醒大家对网络安全的重视&#xff0c;并采取相应的安全措施&#x…

Docker镜像分层

文章目录 docker镜像分层镜像层构成镜像FS 构成基础镜像层扩展镜像层容器层 镜像摘要分发散列值 多架构镜像工作原理 docker镜像分层 Docker 镜像由一些松耦合&#xff08;关系不怎么紧密&#xff09;的只读镜像层组成&#xff0c;Docker Daemon 负责堆叠这些镜像层&#xff0c…

vim安装及使用

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

得物 Android 包体积资源优化实践

包体积优化中&#xff0c;资源优化一般都是首要且容易有成效的优化方向。资源优化是通过优化APK中的资源项来优化包体积&#xff0c;本文我们会介绍得物App在资源优化上做的一些实践。 1. 插件优化 插件优化资源在得物App最新版本上收益12MB。插件优化的日志在包体积平台有具…

Kotlin基础(六):枚举类和扩展

前言 本文主要讲解kotlin枚举类和扩展 Kotlin文章列表 Kotlin文章列表: 点击此处跳转查看 目录 1.1 枚举类 1.1.1 枚举类的基本用法 Kotlin中的枚举类&#xff08;enum class&#xff09;用于定义一组具有预定义值的常量。它们在许多情况下都很有用&#xff0c;例如表示一组…

【外设篇】I2C工作原理

目录 一、I2C 简介 二、I2C 主设备与从设备的关系 三、I2C 数据传输过程 3.1 总线空闲状态 3.2 开始位和停止位的产生 3.3 主设备处于等待状态 3.4 ACK 应答位的产生 3.5 有效的数据传输 3.6 数据的传输 总结 一、I2C 简介 I2C&#xff08;内置集成电路&#…

浏览器 html通知权限已经开了,但是还不提醒

如果您已经在Chrome浏览器中开启了HTML5通知&#xff0c;但是仍然不收到提醒&#xff0c;可能有几种可能的原因。下面是一些建议的解决方法&#xff1a; 检查浏览器设置: 确保HTML5通知在Chrome浏览器中正确启用。您可以按照以下步骤检查设置&#xff1a; 在Chrome中输入 chrom…

【Nacos源码系列】Nacos服务发现的原理

文章目录 服务发现是什么客户端服务发现服务端发现总结 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 上篇文章介绍了 Nacos服务注册的原理 &#xff0c;本篇文章将从客户端和服务端的…

微服务保护——Sentinel【实战篇二】

一、线程隔离 &#x1f349; 线程隔离有两种方式实现&#xff1a; 线程池隔离信号量隔离&#xff08;Sentinel默认采用&#xff09; 线程隔离&#xff08;舱壁模式&#xff09;&#x1f95d; 在添加限流规则时&#xff0c;可以选择两种阈值类型&#xff1a; QPS&#xff1a;…

LiveNVR监控流媒体Onvif/RTSP功能-支持无人机、IPC等设备RTMP推流转码分发H5无插件播放也支持GB28181输出

LiveNVR支持无人机、IPC等设备RTMP推流转码分发H5无插件播放也支持GB28181输出 1、无人机推流转国标2、获取RTMP推流地址2.1、RTMP推流地址格式2.2、推流地址示例 2、设备RTMP推流3、配置拉转RTMP3.1、直播流地址格式3.2、直播流地地址示例3.3、通道配置直播流地址 4、配置级联…

螺杆支撑座的加工工艺

螺杆支撑座是重要的传动元件&#xff0c;一般与滚珠螺杆搭配使用&#xff0c;滚珠螺杆的固定座可选择使用深沟球轴承C7精度&#xff0c;磨削螺杆的固定座可选择用角接触轴承的C5精度&#xff0c;C5的精度更高。 支撑侧没有精度&#xff0c;一般使用深沟球轴承&#xff0c;如果螺…

linux 系统编程-进程中的通信

目录 1 IPC 方法 2管道 2.1管道的概念 2.2 pipe 函数 2.3管道的读写行为 2.4 管道缓冲区大小 2.5 管道的优劣 2.6 FIFO 3.共享存储映射 3.1 文件进程间通信 3.2 存储映射 I/O 3.3 mmap 函数 3.4 munmap 函数 3.5 mmap 注意事项 3.6 mmap 父子进程通信 3.7 mmap …

JAVA 面试准备

这里写自定义目录标题 一、JAVA基础1.ArrayList2.HashMap3.Concurrenthashmap4.Stream5.synchronized6.线程池7.CompletableFuture8.Fork/join9.数组与链表的区别10.单例模式1.饿汉模式2.懒汉模式10.1、 为啥使用synchronized?10.2、 又为啥使用volatile?10.3、 那又又为啥用…