进程间通信—无名管道通信

进程间通信——Interprocess communication——IPC

  每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进程B再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。

  不同进程间的通信本质:进程之间可看到一份公共资源;而提供这份资源的形式或者提供者不同,造成了通信方式不同。

  Linux下进程通信方式主要有以下几种:

  1、管道---pipe

  无名管道:可用于具有亲缘关系进程间的通信(例,fork函数建立父子间通信);

  有名管道:除有与无名管道相同功能外,还允许无亲缘关系进程通信;

  2、信号---signal

  信号是在软件层上对中断机制的模拟,较为复杂,用于通知进程某事发生。

  3、消息队列---message queue

  消息队列是消息的链接表,包括Posix消息队列system V消息队列。有读/写权限的进程可以向队列中添加/读走消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。

  4、共享内存---shared memory

  使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。

  5、信号量---semaphore

  要作为进程间以及同一进程不同线程之间的同步和互斥的手段。

  6、套接口---Socket

  使用更为广泛的进程间通信机制,可用于网络中不同主机之间的进程通信。

一、无名管道

  管道通信会把一个程序的输出直接连接到另外一个程序的输入。

  特点:亲缘关系间通信,单工通信,有固定的读端与写端。

  1、无名管道的创建与关闭

#include <unistd.h>
int pipe (int pfd[2]); 

//成功返回0,错误返回-1

  无名管道由调用pipe函数来创建,是基于文件描述符的通信方式。pfd包含两个元素的整形数组,存放文件描述符。pfd[0]用于读管道, pfd[1]用于写管道。

  管道关闭时只需要close()函数关闭两文件描述符即可。

  2、实现管道通信

  (1)父进程创建管道,得到两个文件描述符指向管道的两端

  (2)父进程fork出子进程,子进程也有两个文件描述符指向同一管道

  (3)父进程关闭fd[0],关闭管道读端,可往管道写;子进程关闭fd[1],关闭管道写端,可从管道读。管道是用环形队列实现的,数据从写端写入,从读端读出,进而实现进程间通信。

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 #include <string.h>
 4 #include <errno.h>
 5
 6 int main(void)
 7 {
 8     int pfd[2];
 9     pid_t pid;
10     int ret;
11
12     /*1.父进程创建管道,得到文件描述符指向管道两端*/
13     ret = pipe(pfd);
14     if(ret == -1)
15     {
16         perror("pipe error\n");
17         return -1;
18     }
19
20     /* 2.父进程fork出子进程,子进程的描述符指向同一管道*/
21     pid = fork();
22     if(pid<0)
23     {
24         perror("fork error\n");
25         return -1;
26     }else if(pid == 0) //子进程关闭pfd[0]写端,ta可以从管道读
27     {
28         close(pfd[0]);
29         char buf[64] = "I am child process!\n";
30         while(1)
31         {
32             write(pfd[1],buf,strlen(buf));
33             sleep(1);
34         }
35     }else  //父进程关闭pfd[1]读端,他可以写入管道
36     {
37         close(pfd[1]);
38         char buf[64];
39         while(1)
40         {
41             memset(buf,0,64); //初始化内存空间,防止打印乱码
42             ret = read(pfd[0],buf,64);
43             if(ret > 0)
44             {
45                 printf("msg from child %s\n",buf);
46             }else{
47                 break;
48             }
49         }
50     }
51 }

pipe_test.c

 

  3.管道读取数据的四种情况

参考:https://blog.csdn.net/skyroben/article/details/71513385

  4、获取管道容量大小

  只要写端一直写,读端不读且不关闭fd[0]

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 #include <string.h>
 4 #include <errno.h>
 5
 6 int main(void)
 7 {
 8     //pfd[0]用于读管道,pfd[1]用于写管道
 9     int pfd[2];
10     pid_t pid;
11     int ret;
12     int i;
13
14     ret = pipe(pfd); //创建管道
15     if(ret < 0)
16     {
17         perror("pipe error!\n");
18         return -1;
19     }
20     //一直写管道,知道堵塞
21     for(i=0; i<1000000; i++)
22     {
23         write(pfd[1],"a",1);
24         printf("i = %d\n",i);
25     }
26
27 }

  写到65535后就发生了管道阻塞,而65536为64K大小即管道容量。

原文地址:https://www.cnblogs.com/y4247464/p/12080201.html

时间: 2024-11-07 03:29:29

进程间通信—无名管道通信的相关文章

无名管道通信

一.核心理论 1.进程通信方式(IPC) (1).通讯的目的: 数据传输,资源共享,通知事件,进程控制 (2).通讯的发展:UNIX进程间的通信.基于System V进程间的通信.POSIX进程间通信 (3).通信方式 : 无名管道(pipe),有名管道(FIFO),信号(signal), 消息队列, 共享内存, 信号量, 套接字(socket) 2.管道通信方式(特点) (1).管道通讯是单向的,有固定的读端和写端 (2).数据被进程从管道读出后,在管道中该数据就不存在了 (3).当进程去读取

进程间通信-无名管道

管道:是一种半双工的通信机制,它一端用来读,另外一端用来写:管道只能用来在具有公共祖先的两个进程之间通信(父进程和子进程或者同一父进程的两个子进程):管道通信消息遵循先进先出的原理,并且数据只能被读取一次,当此段数据被读取后就会清空.管道实质是内存页(page). 相关函数:os.pipe():它返回读写通道文件描述符组成的元组(read_end,write_end). 无名管道示例: import os pi = os.pipe()  #创建管道:(fd_read,fd_write) pid

进程之间通信之有名管道、无名管道(pipe),笔记

             进程之间的通信作用1.数据传输   :一个进程需要将他的数据传到其他进程2.资源共享3.进程通知事件4.进程控制 :有些进程完全控制另一个进程的执行,如调试状态啊我们需要完全控制他的每一步操作: 通信发展历史Linux进程间的通信IPC由以下几个部分发展而来:1.UNIX进程之间的通信2.基于system v进程间的通信3.POSIX进程之间的通信(portable operating system interface) 现在Linux使用的进程间的通信方式包括:1.管

管道通信之无名管道---pipe()

pipe()函数在子进程产生之前就应该存在. 父子进程之间只进行一次传递 1 /*============================================ 2 > Copyright (C) 2014 All rights reserved. 3 > FileName:onepipe.c 4 > author:donald 5 > details: 6 ==============================================*/ 7 #inclu

进程通信-无名管道

无名管道:主要是针对进程通信的(自己感觉它有很大的局限性) 特点:它不是一个文件系统,不能按名访问,这也是它和有名管道之间最大的区别.无名管道只是一个系统内存里面的东西. 半双工模式,数据只能流向一个方向(老师给我们举得例子就是水厂的水到居民用水,不可能倒着流对吧). 进程之间通信,但是只能是有亲缘关系的进程才能进行通信?比如父子进程:因为在父子进程中,子进程拷贝父进程的数据段,这让这两个进程在通信的时候就有了相连的关系. 下面我们来看一下:无名管道的创建,写入,读取,关闭(我用的的是Liunx

linux进程间通信之一:无名管道

无名管道是linux中管道通信的一种原始方法,有以下特征: 1.单工通信模式,具有固定的读端和写端: 2.管道可以看成是一种特殊的文件,对于它的读写可以使用普通的read(),write()等文件IO操作函数接口,但是它不属于任何文件系统,并且只存在与内存中: 3.只能用于具有亲缘关系的进程之间的通信: 4.通常使用时,首先创建一个管道,然后调用fork函数创建一个子进程,该子进程会继承父进程所创建的管道: 5.只有在管道的读端存在时,向管道写入数据才有意义,否则向管道写入的数据的进程将收到内核

IPC通信_无名管道(PIPE)

无名管道只能在具有公共祖先的两个进程间使用,且建议半双工使用(因为历史上就是半双工,虽然有些系统支持全双工管道). 无名管道通过pipe函数创建 #include <unistd.h> int pipe(int fd[2]); 其中:参数fd返回两个文件描述符,fd[0]只用来读,是输出,fd[1]只用来写,是输入. 举例: #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include

Linux进程间通信之管道

1,进程间通信 (IPC ) Inter-Process Communication 比较好理解概念的就是进程间通信就是在不同进程之间传播或交换信息. 2,linux下IPC机制的分类:管道.信号.共享内存.消息队列.信号量.套接字 3,这篇主要说说管道:本质是文件,其他理论什么的网上已经有一大堆了,我就只写一点用法吧. 3.1 特点 1)管道是最古老的IPC,但目前很少使用     2)以文件做交互的媒介,管道分为有名管道和无名管道     3)历史上的管道通常是指半双工管道 3.2 管道:有

进程间通信 之 管道

一 无名管道: 特点: 具有亲缘关系的进程间通信,但不仅仅指父子进程之间哦. (1)无名管道的创建 int pipe(int pipefd 参数: pipefd  数组的首地址 返回值: 成功返回0,失败返回-1 注意: 无名管道存在内核空间,创建成功会给用户空间两个文件描述符,fd[0]:读管道 fd[1]:写管道 思考:为什么无名管道只能用于亲缘关系间进程通信? 因为只有具有亲缘关系的进程存在数据拷贝 [拷贝文件描述符] 二.有名管道 特点: (1)任意进程间通信 (2)文件系统中存在文件名