Linux 进程间通信, 管道

简介: Linux 进程间通信, 管道

前言

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


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

  1. 管道(Pipe):管道是一种基于字节流的进程间通信机制。它将一个进程的输出连接到另一个进 的输入,实现了它们之间的单向通信。管道分为匿名管道和命名管道两种。(使用最简单)
  2. 命名管道(Named Pipe):命名管道(也称为FIFO)是一种有名的管道,它允许不相关的进程通过指定的命名管道文件进行通信。不同于匿名管道,命名管道可以用于不相关的进程之间的通信。
  3. 共享内存(Shared Memory):共享内存是一种高效的进程间通信方式。它允许多个进程共享同一块内存区域,从而避免了复制大量数据的开销。进程可以通过读写共享内存来进行通信和数据交换(无血缘关系)
  4. 信号量(Semaphore):信号量是一种用于进程同步和互斥的系统对象。它用于控制对共享资源的访问,多个进程可以根据信号量的值来进行等待、唤醒和临界区的互斥操作。(开销最小)
  5. 套接字(Socket):套接字是一种用于在网络中进行进程间通信的机制。它可以用于在同一台机器上的进程间通信(本地套接字)或不同机器上的进程间通信(网络套接字)。(最稳定)

二、如何实现管道通信

父进程 在写端 向管道写入数据,子进程 在 读端 从管道读出数据。(父进程 也可以连接 读端,子进程也可以连接 写端)

管道 是一种最基本的 IPC 机制,作用于有血缘关系的进程之间,完成数据传递。

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

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

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

#include <unistd.h>
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]);
  }
}

四、管道的读写行为

读管道:

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

写管道:

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

总结

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

相关文章
|
20天前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
45 1
|
8天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
60 13
|
15天前
|
SQL 运维 监控
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
|
23天前
|
运维 监控 Linux
Linux操作系统的守护进程与服务管理深度剖析####
本文作为一篇技术性文章,旨在深入探讨Linux操作系统中守护进程与服务管理的机制、工具及实践策略。不同于传统的摘要概述,本文将以“守护进程的生命周期”为核心线索,串联起Linux服务管理的各个方面,从守护进程的定义与特性出发,逐步深入到Systemd的工作原理、服务单元文件编写、服务状态管理以及故障排查技巧,为读者呈现一幅Linux服务管理的全景图。 ####
|
1月前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
142 4
linux进程管理万字详解!!!
|
28天前
|
缓存 算法 Linux
Linux内核的心脏:深入理解进程调度器
本文探讨了Linux操作系统中至关重要的组成部分——进程调度器。通过分析其工作原理、调度算法以及在不同场景下的表现,揭示它是如何高效管理CPU资源,确保系统响应性和公平性的。本文旨在为读者提供一个清晰的视图,了解在多任务环境下,Linux是如何智能地分配处理器时间给各个进程的。
|
1月前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
85 8
|
1月前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
90 1
|
1月前
|
Linux
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
|
1月前
|
存储 Unix Linux
进程间通信方式-----管道通信
【10月更文挑战第29天】管道通信是一种重要的进程间通信机制,它为进程间的数据传输和同步提供了一种简单有效的方法。通过合理地使用管道通信,可以实现不同进程之间的协作,提高系统的整体性能和效率。