当前位置: 首页 > 编程日记 > 正文

linux进程通信:pipe实现进程同步

文章目录

        • 通过管道同步进程
        • 实现代码
        • 管道缓冲区
        • 设置缓冲区大小
        • 总结 :pipe的特点

通过管道同步进程

  • 管道自带同步互斥机制:
    • 管道的内核实现:fs/pipe.c ,主要通过内核的锁以及等待队列等机制实现
  • 管道的write操作会阻塞进程
    • 当内存缓冲区已满或被读进程锁定,会阻塞write操作
    • 当所有数据被写入管道时write操作才会结束
  • 管道的read操作会阻塞进程
    • 当读进程被阻塞时会形成等待队列,并让等待队列进入休眠
    • 当所有子进程关闭来管道的写入端的操作时会停止阻塞
    • 父进程的写入端操作关闭时,父进程的读操作会停止阻塞
    • 当所有当写端操作符都被关闭,且管道中当数据都被读出,对读端描述符调用read函数才会返回结束
    • 当所有当读取端和写入端都关闭后,管道才能被销毁

实现代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>#define handle_error(msg)\
{perror(msg);exit(-1);}int main()
{int pipe_fd[2];int buf;printf("parent process(%d) run ...\n",getpid());if (pipe(pipe_fd) == -1)handle_error("pipe");for (int i = 0; i < 4; ++i) {int f;f = fork();if (f == -1)handle_error("fork");if(f == 0){//这里子进程先休眠,然后离开之前关闭所有的读管道if (close(pipe_fd[0]) == -1)_exit(-1);sleep(i * i);printf("child process(%d) closing pipe\n",getpid());if (close (pipe_fd[1]) == -1)_exit(-1);_exit(0);}}//在调用read系统调用之前一定要先关闭进程内所有的写管道,否则读会一直阻塞if (close(pipe_fd[1]) == -1)_exit(-1);// read系统调用正常读取文件会返回大于0都文件字节数。//但是当其读到EOF会返回0,标示读到结束标记//如果返回负数,则标示读取错误if (read(pipe_fd[0] ,&buf,1) != 0) perror("parent read can't get EOF");printf("parent process(%d) exited \n",getpid());return 0;
}

输出如下:

parent process(15454) run ...
child process(15455) closing pipe
child process(15456) closing pipe
child process(15457) closing pipe
child process(15458) closing pipe
parent process(15454) exited 

管道缓冲区

  • 管道对应缓冲区大小
    • PIPE_BUF的容量是有限制的,默认64K
    • 在不同的os下的PIPE_BUF大小设置不同:在limits.h头文件中定义
    • 当写入管道当数据超过PIPE_BUF的时候内核会分割不同的几块进行传输
    • 管道传输容量的缓冲区的容量上限设置不能超过1M
    • 查看打开的管道文件:ls /proc/$pid/fd
      可以在如上代码中的子进程处理代码中的close(pipe_fd[1])之前加入阻塞while(1);
      可以看到父进程有如下文件描述符打开,因为阻塞的子进程中写文件描述符未关闭,所以父进程的读文件描述符未关闭
    zhang@ubuntu:/proc/15521$ ls /proc/15691/fd/
    0  1  2  3
    
    子进程有如下文件描述符打开,因为子进程的写文件描述符关闭,所以4的描述符还存在
    zhanghuigui@ubuntu:/proc/15521$ ls /proc/15692/fd/
    0  1  2  4
    

设置缓冲区大小

  • 特权用户:可以修改缓冲上限
  • 设置缓冲区大小:fcntl(fd,F_SETPIPE_SZ,size)

总结 :pipe的特点

  • 无名管道是字节流
  • 可通过文件I/O接口读写,但是无法lseek修改文件指针的偏移地址
  • 单向阻塞通信:一端用于写入,一端用于读出。实现双向通信需要两个管道
  • 通信简单,性能单一,只能在亲缘进程间通信

相关文章:

(转)MySQL联表查询

资料源于网络 一.内联结、外联结、左联结、右联结的含义及区别在SQL标准中规划的&#xff08;Join&#xff09;联结大致分为下面四种&#xff1a;1.内联结&#xff1a;将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结。2.外联结&#xff1a;分为外左联结和…

极小连通子图和极大连通子图_强连通分量与拓扑排序

前言由于GacUI里面开始多处用上拓扑排序&#xff0c;我决定把之前瞎JB搞出来的算法换掉&#xff0c;换成个正式的。之前我自己弄了个写起来很简单的算法&#xff0c;然后每一处需要用到的地方我就重新做一遍。当然这样肯定也是不行的&#xff0c;我觉得也差不多积累到重构的临界…

INTERVAL数据类型-007学习笔记

http://baggio785.itpub.net/post/31233/286119 INTERVAL数据类型用来存储两个时间戳之间的时间间隔。 可以指定years and months&#xff0c;或者days,hours,minuts,seconds之间的间隔。本文为oracle的学习笔记&#xff0c;结合实例介绍INTERVAL数据类型。 INTERVAL数据类型用…

scrapy模拟用户登录

scrapy框架编写模拟用户登录的三种方式&#xff1a; 方式一&#xff1a;携带cookie登录&#xff0c;携带cookie一般请求的url为登录后的页面&#xff0c;获取cookie信息应在登录后的页面获取&#xff0c;cookie参数应转成字典形式 # -*- coding: utf-8 -*- import re import sc…

linux 系统调用 open函数使用

函数介绍 本文仅仅将open系统调用的使用简单总结一下&#xff0c;关于其实现原理大批的大佬分享可以自行学习。open系统调用主要用于打开或者创建一个文件&#xff0c;并返回文件描述符。 头文件 #include <fcntl.h>函数名称 a. int open(const char *pathname, int fl…

配置zendframework开始工作(加入环境变量)

首先需要把把两个路径加入到环境变量中 1、我用的php环境是xampp&#xff0c;安装在di盘&#xff0c;我要把d:/xampp/php/这个路径加入到环境变量 2、下载zendframework&#xff08;我用的版本是1.&#xff09;,把安装包中的bin目录加入到环境变量 3、关于设置php/php.ini中设置…

mysql计算两gps坐标的距离_mysql 计算两坐标间的距离

mysql 5.6.1 加入了空间数据支持功能&#xff0c;新增了st_*相关函数&#xff0c;可以非常方便的计算两个地理坐标点的距离了。如下例子&#xff1a;按我的坐标计算周边坐标的距离并由近到远排序select name,st_distance(point(113.327955,23.129717),point)*111195 as distanc…

(转)mxArray数据类型

1 、数据类型mxArray的操作 在上节的Matlab引擎函数中&#xff0c;所有与变量有关的数据类型都是mxArray类型。数据结构mxArray以及大量的mx开头的函数&#xff0c;广泛用于Matlab 引擎程序和Matlab C数学库中。mxArray是一种很复杂的数据结构&#xff0c;与Matlab中的array相对…

Bootstrap笔记(记录不会的知识)

head&#xff1a; <link rel"stylesheet" href"bootstrap.min.css" /> 引入bootstrap.min.css文件 <meta name"viewport" content"widthdevice-width,initial-scale1" /> content"widthdevice-width&#xff1a;设为…

linux 系统调用 read,write和lseek 使用

read系统调用 头文件 #include <unistd.h>函数使用 ssize_t read(int fd, void *buf, size_t count) read 函数会从文件描述符fd中读取指定的count长度的内容&#xff0c;并且将读到的结果放入到buf缓冲区中返回值 count 读取成功&#xff0c;则会返回读到的字节数 小于…

简单有趣的matlab小程序_超实用有趣的五个小程序推荐

大家好&#xff0c;我是小胖。废话不多说&#xff0c;进入正题。1.一周CP共读有趣的灵魂总会相遇。一个极简的社交小程序。通过选择自己喜欢的一本书&#xff0c;匹配到那个跟自己有着一样有趣灵魂的TA。选择好要阅读哪本书之后&#xff0c;填写下资料&#xff0c;就能在看一本…

一些linux下的性能监测工具

1.gprof http://blog.csdn.net/stanjiang2010/article/details/5655143 2.系统性能调优 http://www.ibm.com/developerworks/cn/linux/l-time/part2/index.html?cadrs perf http://www.ibm.com/developerworks/cn/linux/l-cn-perf1/ oprofile http://www.ibm.com/developerwor…

uva 10183 How many Fibs?

数学题&#xff1a; 给你一个区间[a,b]在该区间内有多少个费波那列数&#xff08;包括a&#xff0c;b&#xff09;&#xff0c;数据规模达到10^100。 这题的原理很简单&#xff0c;基本没什么算法&#xff0c;其实更偏重于编程能力&#xff0c;需要用到高精度。另外找区间的地方…

2018/11/29 一个64位操作系统的设计与实现 02 (安装nasm)

操作系统: Centos7 在nasm官网上的到通过yum安装nasm的方法 首先在/etc/yum.repos.d/目录下 新建一个名为nasm.repo的文件, 在这么文件中写入内容如下 : [nasm] nameThe Netwide Assembler baseurlhttp://www.nasm.us/pub/nasm/stable/linux/ enabled1 gpgcheck0[nasm-testing]…

a-awk 计算数值最大,最小,平均值并保留指定位数

awk 计算最大值 echo -e "1\n2\n3\n10\n9\n5\n11\n"|awk BEGIN {max 0} {if ($1>max) max$1 } END {print "Max", max} 输出为&#xff1a;Max 11 或者可以使用sort命令更为便捷&#xff1a; cho -e "1\n2\n3\n10\n9\n5\n11\n"|sort -n |tai…

第18章:MYSQL分区

第18章&#xff1a;分区 目录 18.1. MySQL中的分区概述18.2. 分区类型18.2.1. RANGE分区18.2.2. LIST分区18.2.3. HASH分区18.2.4. KEY分区18.2.5. 子分区18.2.6. MySQL分区处理NULL值的方式18.3. 分区管理18.3.1. RANGE和LIST分区的管理18.3.2. HASH和KEY分区的管理18.3.3. 分…

mysql属性配置提高查询_MYSQL性能优化-安装时优化参数配置提高服务性能

MYSQL性能优化一直是个头痛的问题&#xff0c;目前大多都是直接把页面html静态页面或直接使用了缓存技术&#xff0c;下面我就mysql本身的性能优化来分享一下。安装时优化参数配置提高服务性能在Linux下安装Mysql采用默认配置安装的Mysql却未必是工作在最佳性能状态的&#xff…

c++引用的自我见解

2019独角兽企业重金招聘Python工程师标准>>> 刚开始学习c 学完指针后&#xff0c;其细节比较好明白&#xff0c;但学到引用了以后&#xff0c;只知其表却不知其底层的实现机制&#xff0c;虽然知道引用是别名、声明必须同时初始化等等&#xff0c;但这只是概念性的东…

c# yield关键字原理

https://www.cnblogs.com/blueberryzzz/p/8678700.html c# yield关键字原理详解 1.yield实现的功能yield return&#xff1a;先看下面的代码&#xff0c;通过yield return实现了类似用foreach遍历数组的功能&#xff0c;说明yield return也是用来实现迭代器的功能的。 using st…

linux进程间通信:命名管道FIFO

文章目录FIF&#xff2f; 通信特点系统调用接口应用拥有亲缘关系之间的进程通信非亲缘关系进程之间的通信总结FIF&#xff2f; 通信特点 FIFO文件有文件名 可以像普通文件一样存储在文件系统之中可以像普通文件一样使用open/write读写和pipe文件一样属于流式文件&#xff0c;不…

mysql 账户管理_如何用MySQL 命令来实现账户管理

今天我们要学习的是如何用MySQL 命令的方式来对账号进行管理&#xff0c;我们大家都知道在实际应用中MySQL 命令可以完成多种任务&#xff0c;以下的文章主要是对用MySQL 命令的方式来对账号进行管理的具体内容介绍。手册上说 “GRANT语句允许系统管理员创建MySQL用户账户&…

Can't connect to MySQL server on '127.0.0.1' (10061) (code 2003)解决方法

先验证一下MySQL的服务是否开启&#xff0c;到计算机->管理->服务和应用程序->服务 如果服务已开启&#xff0c;就检查一下C:\WINDOWS\system32\drivers\etc目录下的hosts文件&#xff0c; 是否存在这一下&#xff0c;不存在添加。 最后在mysql的配置文件my.ini中[mys…

学习MongoDB (1) :配置安装

为什么80%的码农都做不了架构师&#xff1f;>>> MongoDB是一种强大、灵活、可扩展的数据存储方式。它扩展了关系型数据库的众多有用的功能&#xff0c;如辅助索引、范围查询、排序。 最近开始在Windows 32位平台下研究MongoDB的使用&#xff0c;为了方便&#xff…

跨域策略文件crossdomain.xml文件

使用crossdomain.xml让Flash可以跨域传输数据 一、crossdomain.xml文件的作用 跨域&#xff0c;顾名思义就是需要的资源不在自己的域服务器上&#xff0c;需要访问其他域服务器。跨域策略文件是一个xml文档文件&#xff0c;主要是为web客户端(如Adobe Flash Player等)设置跨…

linux进程间通信:FIFO应用 /var/log/ 系统日志的模拟实现

在类unix操作系统下存在这样一个目录/var/log/&#xff0c;主要是记录操作系统相关的系统各个进程服务的日志信息 该日志系统的特性如下&#xff1a; 支持多进程并发写入同一文件不同进程日志信息可以写入不同文件支持使用head/tail/grep/cat/vi 等命令进行日志操作 我们可以…

context.xml mysql_在tomcat下context.xml中配置各种数据库连接池(示例代码)

Tomcat6的服务器配置文件放在 ${tomcat6}/conf 目录底下。我们可以在这里找到 server.xml 和 context.xml。当然&#xff0c;还有其他一些资源文件。但是在在本文中我们只用得上这两个&#xff0c;其他的就不介绍了。1,首先&#xff0c;需要为数据源配置一个JNDI资源。我们的数…

Planetary.js:帮助你构建超炫的互动球体效果

Planetary.js 是一个 JavaScript 库&#xff0c;用于构建互动球体效果。它使用 D3 和 TopoJSON 解析和渲染地理数据。Planetary.js 采用了基于插件的架构&#xff0c;即使是默认的功能是作为插件实现的&#xff0c;这使得 Planetary.js 非常灵活。Planetary.js 是完全可定制&am…

JAVA条件表达式的陷阱

Map<String, Integer> map new HashMap<String, Integer>(); map.put("count", null); Integer it map null ? 0 : map.get("count"); 注意&#xff1a;在第三行&#xff0c;会抛出java.lang.NullPointerException信息。因为分析&…

腾讯Bugly异常崩溃SDK接入

首先登入Bugly&#xff0c;创建应用&#xff0c;记录下AppId ①下载SDK&#xff0c;通过Cocoapods集成 pod Bugly #腾讯异常崩溃日志服务 ②导入头文件&#xff0c;并初始化 /** 腾讯Bugly */#import <…

linux进程间通信:FIFO实现进程间的双向通信

fifo的双向通信的方式如下图&#xff1a; 两个进程间的通信需要两个命名管道&#xff0c;分别处理一个进程的读和写 导致这种通信方式出现的根因还是由于fifo的阻塞读和阻塞写&#xff0c;所以这里需要使用两个管道对读写进行分别处理。 同时因为管道传输的数据为流式数据&…