进程间通讯(IPC)(1)———管道

提出疑问

每个进程有自己独立的用户地址空间,一个进程的全局变量在另一个进程中可以看到吗?

我们用下面这个程序来进行测试:

验证结果:

可以看出:在父进程中的全局变量,如果在子进程中去改变这个全局变量,则子进程中被改变的这个值不会去影响父进程,因为子进程中的所有数据都是通过写时拷贝拷自父进程的,这两个进程的地址空间就是不同的了。

进程间通信概念:进程用户空间是相互独立的,一般而言是不能相互访问的。但很多情况下进程间需要互相通信,来完成系统的某项功能。进程通过与内核及其它进程之间的互相通信来协调它们的行为。

进程间通讯应用场景:

  1. 数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几兆字节之间。
  2. 共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到。 
  3. 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
  4. 资源共享:多个进程之间共享同样的资源。为了作到这一点,需要内核提供锁和同步机制。    
  5. 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。  

 今天我们就来看一些进程间通讯的方式,进程间的通讯方式有5种:管道,消息队列,信号量,共享内存,socket。今天我们谈一下第一种通讯方式:管道。

管道:管道类似于一种特殊的文件(并不是属于某文件系统),它存在于内存中,进程可以对它进行读写,它提供流控制,保证进程的正确读写,即管道为空时读进程会阻塞,管道为满时写进程会阻塞,以此实现进程之间的通信。

管道可以分为两类,即:有名管道,无名管道。

 1.无名管道

它是半双工的,即数据只能单向传输。它是有进程关系限制的,只能在父子进程或者兄弟进程之间使用,双方在进行通信时,需要建立起两个管道。单独构成一个独立的文件系统,管道对于两端的进程而言就是一个文件,但它并不是普通的文件,他不属于某种文件系统,并且只存在内存中。数据的读出和写入,一个进程向管道中写的内容被另一端进程读出。写入的内容每一次都添加在管道缓冲区的末尾,并且每次都是从缓冲区头部读出数据,向管道中写入数据时,Linux将不保证写入的原子性,管道缓冲区有空闲时,写进程就会写入数据,如果进程不读走,写操作会一直阻塞。

   管道的原型:

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

当一个管道建立时,它会创建两个文件描述符:fd[0]为读而打开,fd[1]为写而打开。如下图:

要关闭管道只需要将这两个文件描述符关掉就行了。

单个进程中的管道几乎没有任何用处。所以,通常调用 pipe 的进程接着调用 fork,这样就创建了父进程与子进程之间的 IPC 通道。如下图所示:

若要数据流从父进程流向子进程,则关闭父进程的读端(fd[0])与子进程的写端(fd[1]);反之,则可以使数据流从子进程流向父进程。 

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

int main()
 {
     int fd[2];
     pid_t pid;
     char buff[20];
 
     if(pipe(fd) < 0)  // 创建管道        
     printf("Create Pipe Error!\n");
 
     if((pid = fork()) < 0)  // 创建子进程
         printf("Fork Error!\n");
     else if(pid > 0)  // 父进程
     {
         close(fd[0]); // 关闭读端
         write(fd[1], "hello world\n", 12);
     }
    else
     {
         close(fd[1]); // 关闭写端
         read(fd[0], buff, 20);
         printf("%s", buff);
     }
     return 0;
 }

 2.有名管道(FIFO)

有名管道可以看成是有文件名标识的一个管道,不同于无名管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样即使与FIFO创建进程不存在亲缘关系,只要访问该路径,就能够彼此通过FIFO相互通信,因此,通过FIFO不相关的进程也能交换数据。FIFO严格遵守先进先出,对管道及FIFO的读总是从开始处返回数据对他们的写则添加数据到末尾。从结构上来看无名管道没有文件路径名,不占用文件目录项,因此文件目录结构中的链表,不适用于这种结构,他只是存在于打开文件结构中的一个临时文件,随其依附的进程的生存而生存,当进程终止,无名管道也随之消亡。

1、特点

2、原型 

  1. FIFO可以在无关的进程之间交换数据,与无名管道不同。

  2. FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。

  3. 1.#include <sys/stat.h>
    2.// 返回值:成功返回0,出错返回-1
    3.int mkfifo(const char *pathname, mode_t mode);

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值