Linux 进程间通信, 管道

文章目录

  • 前言
  • 一、常见的进程间通信方式
  • 二、如何实现管道通信
  • 三、示例代码解析
  • 四、管道的读写行为
  • 总结

前言

在多进程编程中,进程间通信(Inter-Process Communication,IPC)是一种重要的技术手段,它使得不同进程可以安全、可靠地进行数据交换和共享资源。


一、常见的进程间通信方式

  1. 管道(Pipe):管道是一种基于字节流的进程间通信机制。它将一个进程的输出连接到另一个进 的输入,实现了它们之间的单向通信。管道分为匿名管道和命名管道两种。(使用最简单)

  2. 命名管道(Named Pipe):命名管道(也称为FIFO)是一种有名的管道,它允许不相关的进程通过指定的命名管道文件进行通信。不同于匿名管道,命名管道可以用于不相关的进程之间的通信。

  3. 共享内存(Shared Memory):共享内存是一种高效的进程间通信方式。它允许多个进程共享同一块内存区域,从而避免了复制大量数据的开销。进程可以通过读写共享内存来进行通信和数据交换。(无血缘关系)

  4. 信号量(Semaphore):信号量是一种用于进程同步和互斥的系统对象。它用于控制对共享资源的访问,多个进程可以根据信号量的值来进行等待、唤醒和临界区的互斥操作。(开销最小)

  5. 套接字(Socket):套接字是一种用于在网络中进行进程间通信的机制。它可以用于在同一台机器上的进程间通信(本地套接字)或不同机器上的进程间通信(网络套接字)。(最稳定)


二、如何实现管道通信

父进程 在写端 向管道写入数据,子进程 在 读端 从管道读出数据。(父进程 也可以连接 读端,子进程也可以连接 写端)
Linux 进程间通信, 管道_第1张图片
管道 是一种最基本的 IPC 机制,作用于有血缘关系的进程之间,完成数据传递。

  1. 管道的特性:
  • 本质是一个伪文件。
  • 由 2 个文件描述符引用,一个表示读端,一个表示写端
  • 规定数据从管道的写端流入管道,从 读端流出。
  1. 管道的局限性:
  • 数据不能 该进程自己写,自己读。
  • 管道中数据不可反复读取。一旦读走,管道中不在存在。
  • 采用半双工通信方式,数据只能在单方向上流动。
  • 只能在共有祖先的基础上使用管道。
  1. pipe 函数 创建,打开 管道

使用 pipe() 函数进行进程间通信时,需要进程具有血缘关系,通常是父子进程之间。如无血缘关系的进程或完全独立的线程,无法直接使用 pipe() 函数进行通信。

pipe 参数为一个数组, 里面有两个句柄(读 写,分别对应管道的读端,写端)。规定: fd[0] --> r ; fd[1] --> w

#include 

int pipe(int pipefd[2]);

返回值: 成功返回 0,失败返回 -1。
在这里插入图片描述

三、示例代码解析

STDOUT_FILENO:这是一个预定义的常量,表示标准输出的文件描述符。

void sys_error(const char *str)
{		
	perror(str);					// 将最近一次发生的系统调用错误输出到标准错误流
	exit(1);					// 正常终止程序
}

int main(void)
{
   	int fd[2];
	int ret;
 	pid_t pid;
	char buff[20] = "hello pipe!\n";
	char str[20];

	ret = pipe(fd);							// 创建,打开管道
	if(ret == -1)
	{
		sys_error("pipe error!");
	}
	
	pid = fork();								//创建子进程
	if(pid == 0)							
	{
		close(fd[0]);							//子进程 关闭读端
		write(fd[1], buff,sizeof(buff));			//向管道写入数据
		close(fd[1]);
	}
	else 			
	{
		close(fd[1]);							//父进程 关闭写端
		ret = read(fd[0],str,sizeof(str));				//从管道读出数据
		write(STDOUT_FILENO, str,sizeof(str));			// 将 str 写入标准输出中
		close(fd[0]);
	}
}

Linux 进程间通信, 管道_第2张图片

四、管道的读写行为

读管道:

  1. 管道有数据,read 返回实际独到的字节数。
  2. 管道无数据:
  • 无写端, read 返回 0。
  • 有 写端, read 阻塞等待。

写管道:

  1. 管道 无 读端, 异常终止。
  2. 管道 有 读端:
  • 管道 已满,阻塞等待。
  • 管道未满,返回写出的字节个数。

总结

进程间管道通信是一种基本而有效的进程间通信机制,在多进程编程中扮演着重要角色。

你可能感兴趣的:(linux,服务器,linux,运维,管道,pipe)