自学嵌入式day34,ipc进程间通信

IPC(进程间通信)概述

进程空间独立,但进程间常需数据共享或交换,因此需要IPC机制。IPC允许不同进程高效协作,例如数据传输、同步操作等。IPC方式多样,可根据需求选择。

IPC主要种类
  1. 古老通信方式:包括无名管道、有名管道和信号。
  2. IPC对象通信:如共享内存、信号量集(消息队列相对少用)。
  3. Socket通信:适用于网络环境。

管道底层实现基于队列,支持高效数据传输。下面重点讨论无名管道和有名管道。


无名管道(匿名管道)

无名管道仅适用于有亲缘关系的进程(如父子进程)。它基于文件描述符操作,特性如下:

  • 半双工模式:通常用作单工(单向通信)。
  • 不支持定位操作(如lseek)。
  • 使用文件IO(open, read, write, close)或标准IO(带缓冲区)。
  • 阻塞行为:
    • 读端存在时,写操作超过64KB会阻塞。
    • 写端存在时,读操作在管道为空时会阻塞。
    • 读端关闭后,写操作会导致写进程退出。
    • 写端关闭后,读操作返回0表示结束。
编程步骤
  1. 创建管道。
  2. 读写管道。
  3. 关闭管道。
函数原型
c 复制代码
int pipe(int pipefd[2]);
  • 功能:创建并打开无名管道。
  • 参数 :
    • pipefd[0]:固定读端。
    • pipefd[1]:固定写端。
  • 返回值:成功返回0,失败返回-1。

示例使用:

c 复制代码
#include <unistd.h>
#include <stdio.h>

int main() {
    int pipefd[2];
    pid_t pid;
    
    if (pipe(pipefd) == -1) {
        perror("pipe error");
        return -1;
    }
    
    pid = fork();
    if (pid == 0) { // 子进程:写数据
        close(pipefd[0]); // 关闭读端
        write(pipefd[1], "Hello", 6);
        close(pipefd[1]);
    } else if (pid > 0) { // 父进程:读数据
        close(pipefd[1]); // 关闭写端
        char buf[10];
        read(pipefd[0], buf, sizeof(buf));
        printf("Received: %s\n", buf);
        close(pipefd[0]);
    }
    return 0;
}

有名管道

有名管道(FIFO)适用于任意单机进程,在文件系统中可见(有路径名)。特性与无名管道一致,额外特性:

  • 一端未打开时,open函数会阻塞。
编程步骤
  1. 创建有名管道。
  2. 打开有名管道。
  3. 读写管道。
  4. 关闭管道。
  5. 卸载有名管道(可选)。
函数原型
c 复制代码
int mkfifo(const char *pathname, mode_t mode);
  • 功能:创建有名管道文件。
  • 参数 :
    • pathname:文件路径和名称。
    • mode:八进制权限(如0666)。
  • 返回值:成功返回0,失败返回-1。

示例使用:

c 复制代码
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    const char *fifo_path = "/tmp/myfifo";
    
    // 创建有名管道
    if (mkfifo(fifo_path, 0666) == -1) {
        perror("mkfifo error");
        return -1;
    }
    
    // 进程A:写数据
    int fd = open(fifo_path, O_WRONLY);
    write(fd, "Data from A", 12);
    close(fd);
    
    // 进程B:读数据
    fd = open(fifo_path, O_RDONLY);
    char buf[20];
    read(fd, buf, sizeof(buf));
    close(fd);
    
    // 可选:卸载管道
    unlink(fifo_path);
    return 0;
}

总结

  • 无名管道适合亲缘进程,简单高效。
  • 有名管道扩展至任意进程,但需文件系统管理。
  • 管道通信需注意阻塞和关闭行为,避免死锁或数据丢失。实际应用中,结合进程同步机制(如信号量)可增强可靠性。
相关推荐
码间留白19 分钟前
手把手把 GitHub 推上阿里云 ECS:Actions CI/CD 全链路避坑实录(折腾好几天,到 2 分钟见绿)
运维·阿里云·ci/cd·docker·devops·github actions
吹什么轩2 小时前
linux系统复习:僵尸进程与孤儿进程
linux·运维·php
张宇Joaquin2 小时前
AMD uProf 工具采集微架构特征使用介绍
服务器
殷忆枫2 小时前
告别依赖地狱!在 Ubuntu 上用 Docker 极速部署 Home Assistant 与 MQTT,并接入 Siri 与嵌入式 C 终端
linux·ubuntu·docker
第404号工位2 小时前
手机到底有没有偷听我们?我抓包了 72 小时,抓到了真凶
linux·人工智能·架构
老李IT笔记2 小时前
连不上不一定是网不好:新系统不认的服务端配置卡在哪一档
运维·服务器·网络
字节跳动开源2 小时前
ByteDance 2026 上半年 Linux 内核贡献回顾
linux·开源
小此方3 小时前
Linux网络(二十八):从NAT转换到正反向代理:图解内网通信、NAPT端口映射
linux·运维·网络
刚入门的大一新生3 小时前
Linux-进程池
linux·运维·服务器
数据库小学妹3 小时前
数据库运维五级成熟度:监控、备份、高可用怎么串起来
运维·数据库·监控