Linux编程练习 --进程间通信1--无名管道

进程间通信系列--管道

管道可以说是最古老的IPC形式,所谓管道,是指进程间建立的一条通信的通道,从本质上看,管道是UNIX文件概念的推广管道通信的介质是文件,先看一下管道的特点:

 

1.管道的特点:

  (1)管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;

  (2)无名管道只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);后来发展了FIFO(也称有名管道)

  (3)单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。

   (4)数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。

 

2.无名管道API及操作:

头文件:#include <unistd.h>

数据成员:int pipe_fd[2];

管道创建:int pipe(int fd[2])

    该函数创建的管道的两端处于一个进程中间,在实际应用中没有太大意义,因此,一个进程在由pipe()创建管道后,一般再fork一个子进程,然后通过管道实现父子进程间的通信(因此也不难推出,只要两个进程中存在亲缘关系,这里的亲缘关系指的是具有共同的祖先,都可以采用管道方式来进行通信)。

管道读写:

管道两端可分别用描述字fd[0]以及fd[1]来描述,管道读端:fd[0],管道写端:fd[1];

读管道规则:

 关闭管道的写端:close (fd[WRITE]);

读出:read(fd[READ],string,strlen(string));

读出后关闭管道的读端:close(fd[REAd]);

 

写管道规则:

关闭管道的读端:close(fd[REAd]);

写入:write(fd[WRITE],string,strlen(string));

写入后关闭管道的写端:close (fd[WRITE]);

 

下面练习一个简单的单管道通信:

父进程写数据,子进程负责读出数据

 

[cpp] view plaincopy
  1. /**************  
  2.   * readtest.c *  
  3.    
  4. **************/   
  5. #include <unistd.h>   
  6. #include <sys/types.h>   
  7. #include <errno.h>   
  8. #define     READ    0  
  9. #define     WRITE   1  
  10. main()   
  11. {     
  12.     int pipe_fd[2];       
  13.     pid_t pid;    
  14.     char r_buf[100];      
  15.     char w_buf[32];       
  16.     char* p_wbuf;   
  17.     int r_num;    
  18.     int cmd;      
  19.     memset(r_buf,0,sizeof(r_buf));    
  20.     memset(w_buf,0,sizeof(r_buf));    
  21.     p_wbuf=w_buf;     
  22.     if(pipe(pipe_fd)<0)        
  23.     {         
  24.         printf("pipe create error ");         
  25.         return -1;        
  26.     }   
  27.       
  28.     if((pid=fork())==0) //子进程读        
  29.     {     
  30.         close(pipe_fd[WRITE]);    
  31.         sleep(3);           //确保父进程关闭写端   
  32.         r_num=read(pipe_fd[READ],r_buf,100);   
  33.         printf( "read num is %d the data read from the pipe is %s /n",r_num,r_buf);       
  34.         close(pipe_fd[READ]);     
  35.         exit();           
  36.     }     
  37.     else if(pid>0)   //父进程写  
  38.     {         
  39.         close(pipe_fd[READ]);         
  40.         strcpy(w_buf,"hello world!/n");           
  41.         if(write(pipe_fd[WRITE],w_buf,strlen(w_buf))==-1)         
  42.             printf("parent write over/n ");           
  43.         close(pipe_fd[WRITE]);        
  44.         printf("parent close fd[WRITE] over /n");         
  45.         sleep(10);   
  46.     }     
  47. }   

编译运行,看到预期结果

 

3.利用两个管道进行双向通信

(1)创建两个管道:管道1(父->子),管道2(子->父)

(2)fork()产生子进程

(3)父进程:close(fd1[READ]); close(fd2[WRITE]);

(4)子进程:close(fd1[WRITE]); close(fd2[READ]);

下面做一个练习,是利用双向通信实现父子进程协作把整数x从1加到10

[cpp] view plaincopy
  1. #include <unistd.h>  
  2. #include <sys/stat.h>  
  3. #include <sys/types.h>  
  4. #include <stdio.h>  
  5. #include <fcntl.h>  
  6. #define MAXLINE 1024  
  7. #define READ    0  
  8. #define WRITE   1  
  9. main(void)  
  10. {  
  11.     int x;  
  12.     pid_t pid;  
  13.     int pipe1[2],pipe2[2];  
  14.     /*初始化管道*/  
  15.     pipe(pipe1);  
  16.     pipe(pipe2);  
  17.     pid = fork();  
  18.     if(pid < 0)  
  19.     {  
  20.         printf("create process error!/n");  
  21.         exit(1);  
  22.     }  
  23.     if(pid == 0)        //子进程  
  24.     {  
  25.         close(pipe1[WRITE]);  
  26.         close(pipe2[READ]);  
  27.         do  
  28.         {  
  29.             read(pipe1[READ],&x,sizeof(int));  
  30.             printf("child %d read: %d/n",getpid(),x++);  
  31.             write(pipe2[WRITE],&x,sizeof(int));  
  32.         }while(x<=9);  
  33.         //读写完成后,关闭管道  
  34.         close(pipe1[READ]);  
  35.         close(pipe2[WRITE]);  
  36.         exit(0);  
  37.     }  
  38.     else if(pid > 0) //父进程  
  39.     {  
  40.         close(pipe2[WRITE]);  
  41.         close(pipe1[READ]);  
  42.         x = 1;  
  43.         //每次循环向管道1 的1 端写入变量X 的值,并从  
  44.         //管道2 的0 端读一整数写入X 再对X 加1,直到X 大于10  
  45.         do{  
  46.             write(pipe1[WRITE],&x,sizeof(int));  
  47.             read(pipe2[READ],&x,sizeof(int));  
  48.             printf("parent %d read: %d/n",getpid(),x++);  
  49.         }while(x<=9);  
  50.         //读写完成后,关闭管道  
  51.         close(pipe1[WRITE]);  
  52.         close(pipe2[READ]);  
  53.         waitpid(pid,NULL,0);  
  54.         exit(0);  
  55.     }  
  56. }  

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

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

相关文章

2.3 Factory Method(工厂方法)

【返回目录】 我们现在把场景从险象丛生的特工战切换到更为壮观的二战中来&#xff0c;很多人都看过《拯救大兵瑞恩》&#xff0c;这部电影最著名的两场战斗非首和尾莫属&#xff0c;我们就用最后一场战役来举例说明什么是工厂方法吧。 相比诺曼底登陆&#xff0c;最后一场战役…

【转】CreateWindow函数详解

CreateWindow函数详解 在注册完窗口类后就需要进行窗口的创建&#xff0c;用到的函数理所当然就是CreateWindow()&#xff0c; 而这个函数是基于窗口类的&#xff0c;所以还需要指定几个参数来制定特定的窗口。而且像一些不带边框的窗口是怎么创建的也是具有相当的技巧的&#…

java中处理打折率_【JAVA300例】13、输入价格判断折扣,switch用法+int留整数方便判断...

import java.util.Scanner;public class Test013{public static void main(String[] args){Scanner in new Scanner(System.in);System.out.println("请输入金额(整数):");float money in.nextFloat();String zhekou "";if (money>1200){int grade …

[转] UML中关联、依赖、聚集等关系的异同

1. 关联&#xff1a;连接模型元素及链接实例&#xff0c;用一条实线来表示&#xff1b;2. 依赖&#xff1a;表示一个元素以某种方式依赖于另一个元素&#xff0c;用一条虚线加箭头来表示&#xff1b;3. 聚集&#xff1a;表示整体与部分的关系&#xff0c;用一条实线加空心菱…

【转】C++ _T()函数和_L()函数介绍

_T("")是一个宏,他的作用是让你的程序支持Unicode编码&#xff0c;因为Windows使用两种字符集ANSI和UNICODE&#xff0c; 前者就是通常使用的单字节方式&#xff0c;但这种方式处理象中文这样的双字节字符不方便&#xff0c;容易出现半个汉字的情况。 而后者是双字节…

Linux编程练习 --进程间通信2--两个管道实现双向通信

利用两个管道进行进程间双向通信在第一篇练习已经大致作出说明&#xff0c;下面将进行一个更为综合的练习 首先看题目&#xff1a; 设有二元函数f(x,y) f(x) f(y) 其中&#xff1a; f(x) f(x-1) * x (x >1) f(x)1 (x1) f(y) f(y-1) f(y-2) (y> 2) f(y)1 (y1,2) 请编…

Windows集群网络配置最佳做法

要开始做集群了&#xff0c;找点资料来看看&#xff1a;阅读提示&#xff1a;本文为 Microsoft Windows 2000 或 Windows Server 2003 服务器群集的网络基础结构提供了服务器群集要求和最佳做法。若要群集可以正常运行&#xff0c;必须满足这些要求。最佳做法是从部署反馈和现场…

JOJ的2042面试题目的数学推导过程

JOJ的2042题目是一个程序理解题目&#xff0c;这个题目非常有意思&#xff0c;给出了下面一段C源代码&#xff0c;要求计算出最后的输出结果&#xff0c;源代码如下&#xff1a; #include<cstdio> int main(void) { int x 987654321, c 0, d 1, e 6; while…

linux mysql密码转义_linux忘记mysql密码处理方法

linux忘记mysql密码处理方法:# /etc/init.d/mysql stop# mysqld_safe --usermysql --skip-grant-tables --skip-networking &# mysql -u root mysqlmysql> update user set passwordpassword(newpassword) where userroot;mysql> flush privileges;mysql> quit# /…

不同职业的面试着装技巧。

美女姜培琳&#xff1a;传授独家心经 不同职业的面试着装技巧。 一般来说&#xff0c;职场中精英女性的装扮&#xff0c;首要应讲求端庄、稳重。人们对服饰过于花哨怪异者的工作能力、工作作风、敬业精神、生活态度等&#xff0c;都会持怀疑的态度。 其实&#x…

ARMV4,ARMV4T,ARMV4I的意义

ARMV4,ARMV4T,ARMV4I 以上表示的是指令的版本 也就是三种指令集&#xff1a; ARMv4 -> 它只支持 32 位 ARMv4 指令 ARMv4T ->“T”代表 Thumb(16 位指令模式) ARMv4I ->“I”代表交互作用 (Interworking)。它允许 32 位指令和 16 位指令共存 一些经常出现的CPU支持的指…

【转】C++中的字符串(String)和数值转换

『写在前边』 因为写PAT总是遇到字符串&#xff08;主要是String&#xff09;和数值之间的转化&#xff0c;所以整理一下以便好复习。 『String类型的字符串』 这里数值和字符串相互转换的例子&#xff0c;使用的是stringstream函数&#xff0c;在c11当中有定义好的现成的函数…

好开心

好开心&#xff01;收到我们家lily的礼物&#xff01; 前天&#xff0c;lily传给我一个flash相册&#xff0c;他将我们认识以来的合照做成了flash&#xff0c;配上了音乐。看了好感动&#xff0c;好开心&#xff01; 其实照片倒不是很多&#xff0c;也就7到8张吧&#xff0c;但…

java 实现真正的随机数_关于java:SecureRandom的Android实现是否产生真正的随机数?...

我已经阅读过&#xff0c;一般来说&#xff0c;SecureRandom的一些实现可能会产生真正的随机数。特别是&#xff0c;Android文档说instances of this class will generate an initial seed using an internal entropy source, such as /dev/urandom号但这是否意味着它将产生真正…

etherpeek nx在网络维护中的应用

摘要&#xff1a;该文分析了etherpeek nx的工作原理&#xff0c;主要利用etherpeek nx的数据包截取和分析功能来对netrobocop&#xff08;网络执法官&#xff09;数据包的分析&#xff0c;了解局域网和netrobocop的基本原理&#xff0c;从而更好地维护网络的安全和畅通。 关键…

【转】Windows编程之hdc和hwnd的区别

在windows编程中类型名前面加H的基本是句柄常用句柄 : HBITMAP 保存位图信息的内存域的句柄 HBRUSH 画刷句柄 HCTR 子窗口控件句柄 HCURSOR 鼠标光标句柄 HDC 设备描述表句柄 HDLG 对话框句柄 HFONT 字体句柄 HICON 图标句柄 HINSTANCE 应用程序实例句柄 HMENU 菜单句柄 HMODUL…

java在dos中如何测试_[求助]怎么在java中模拟dos命令行

[CODE]/** Test.java** Created on 2006年12月21日, 下午3:53** To change this template, choose Tools | Template Manager* and open the template in the editor.*/package testCMD;/**** author lbf*/import java.io.*;import java.awt.*;import java.awt.event.*;import …

谈谈基于SQL Server 的Exception Handlingp[下篇]

六、SqlException 在上面一节中&#xff0c;我给出了一个完整的例子说明了&#xff1a;如何在将message定义在sys.messages中保证message的一致性和可维护性&#xff1b;如何在Stored procedure中使用RAISERROR将一个可预知的Error抛出&#xff1b;如何在Stored procedure中使用…

char * 转LPCTSTR若干方法

如何将char* 转换为LPCTSTR&#xff1f;&#xff1f; rainForestBache (百奇) 2004-10-19 20:17:48 在 VC/MFC / 基础类 提问 请多多指教 问题点数&#xff1a;20、回复次数&#xff1a;10 1楼 stephen_young () 回复于 2004-10-19 20:33:45 得分 5 实际上将char*转…

【转】修改static控件背景颜色和文字颜色

当 static 控件或具有 ES_READONLY 风格的 edit 控件被绘制时&#xff0c;会向父窗口发送 WM_CTLCOLORSTATIC 消息。如果我们在窗口过程中处理该消息&#xff0c;就必须返回一个画刷句柄&#xff0c;Windows 会使用该画刷来绘制控件背景&#xff08;子窗口背景&#xff09;。 也…