Linux软件编程学习笔记(八):进程间通信详解(1)

前言

进程间通信(Inter-Process Communication,IPC)是指在操作系统中,不同进程之间交换数据和信息的技术。由于进程空间是独立的,每个进程独享自己的0-4G虚拟内存空间,因此需要借助特定的机制来实现进程间的数据交换。本文将详细介绍Linux下常用的进程间通信方式。


一、进程间通信概述

1. 进程间通信的必要性

  • 进程空间是独立的,无法直接访问其他进程的内存空间
  • 多个进程协同工作需要进行数据交换
  • 进程间通信是构建复杂应用程序的基础

2. 进程间通信的方法

  1. 管道(无名管道、有名管道)
  2. 信号
  3. 消息队列
  4. 共享内存
  5. 信号灯

二、管道通信

1. 无名管道

1.1 概念

无名管道只能用于具有亲缘关系的进程间通信(如父子进程之间)。

1.2 函数接口

pipe函数

c 复制代码
int pipe(int pipefd[2]);
  • 功能:创建一段用于进程间通信的内核缓存区
  • 参数 :
    • pipefd[0]:读文件描述符
    • pipefd[1]:写文件描述符
  • 返回值:成功返回0,失败返回-1
1.3 管道特性

关于写端:

  • 管道中有写端存在时:
    • 管道中有数据则阻塞等待直到数据被读出
  • 管道中没有写端时:
    • 管道中有数据则直接读出
    • 管道中没有数据则直接结束,不需要阻塞等待

关于读端:

  • 管道中有读端存在时:
    • 如果管道没有写满(64K),直接写入数据
    • 如果管道已写满,则需要有数据读出才能继续写入
  • 管道中没有读端时:
    • 写入数据会产生管道破裂的错误,使进程直接退出

2. 有名管道(FIFO)

2.1 概念

有名管道可以用于任意两个进程间的通信,不局限于具有亲缘关系的进程。

2.2 函数接口

mkfifo函数

c 复制代码
int mkfifo(const char *pathname, mode_t mode);
  • 功能:创建一个有名管道文件
  • 参数 :
    • pathname:有名管道的路径
    • mode:权限(如0664)
  • 返回值:成功返回0,失败返回-1
2.3 特性说明
  • 读写两端必须同时加入才能继续向下执行
  • 如果只有读端或写端,则会阻塞等待直到另一端加入
2.4 聊天程序示例

write.c(负责发送数据)

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

int main(void)
{
    int fd = open("/tmp/fifo", O_WRONLY);
    char buf[1024] = {0};
    
    while (1) {
        gets(buf);
        write(fd, buf, strlen(buf));
    }
    
    close(fd);
    return 0;
}

read.c(负责接收数据)

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

int main(void)
{
    mkfifo("/tmp/fifo", 0664);
    int fd = open("/tmp/fifo", O_RDONLY);
    char buf[1024] = {0};
    
    while (1) {
        read(fd, buf, sizeof(buf));
        printf("收到消息:%s\n", buf);
    }
    
    close(fd);
    return 0;
}

三、信号通信

1. 信号概述

信号是内核层与应用层通信的一种机制,用于通知进程发生了某种事件。

2. 信号处理方式

  1. 缺省:按照默认方式处理信号
  2. 忽略:不处理信号
  3. 捕捉:按照指定的方式处理信号

3. 常见信号类型

信号编号 信号名称 说明
2 SIGINT 从键盘输入Ctrl+C产生
3 SIGQUIT 从键盘输入Ctrl+\产生
9 SIGKILL 不能被忽略和捕捉
11 SIGSEGV 段错误信号
13 SIGPIPE 管道破裂信号
14 SIGALRM 定时时间到达信号
17 SIGCHLD 子进程结束信号
19 SIGSTOP 暂停信号
20 SIGTSTP 挂起信号(Ctrl+Z)

4. 函数接口

4.1 signal函数
c 复制代码
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
  • 功能:改变信号的处理方式
  • 参数 :
    • signum:信号的编号
    • handler:
      • SIG_IGN:忽略信号
      • SIG_DFL:缺省处理信号
      • 自定义函数指针:捕捉信号
  • 返回值:成功返回上一次注册的信号处理方式,失败返回SIG_ERR

使用示例:

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

void handler(int signum)
{
    printf("收到信号:%d\n", signum);
}

int main(void)
{
    // 捕捉SIGINT信号
    signal(SIGINT, handler);
    
    // 忽略SIGQUIT信号
    signal(SIGQUIT, SIG_IGN);
    
    while (1) {
        sleep(1);
    }
    
    return 0;
}
4.2 pause函数
c 复制代码
int pause(void);
  • 功能:让进程睡眠,直到收到信号
4.3 alarm函数
c 复制代码
unsigned int alarm(unsigned int seconds);
  • 功能:隔seconds秒后给调用进程发送SIGALRM信号

使用示例:

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

void handler(int signum)
{
    printf("定时时间到!\n");
    alarm(2);  // 重新定时
}

int main(void)
{
    signal(SIGALRM, handler);
    alarm(2);  // 2秒后发送SIGALRM信号
    
    while (1) {
        pause();  // 等待信号
    }
    
    return 0;
}

四、其他进程间通信方式

1. 消息队列

消息队列是内核中存放消息的链表,允许多个进程向同一个队列读写消息。

2. 共享内存

共享内存是最快的IPC方式,多个进程共享同一块物理内存区域,无需数据复制。

3. 信号灯

信号灯(信号量)主要用于进程间同步,控制多个进程对共享资源的访问。


总结

本文详细介绍了Linux下进程间通信的几种主要方式:

  1. 无名管道:适用于有亲缘关系的进程间通信
  2. 有名管道:适用于任意进程间的通信
  3. 信号:内核与应用层通信的异步通知机制

在实际开发中,需要根据具体场景选择合适的IPC方式:

  • 简单数据流通信:使用管道
  • 异步事件通知:使用信号
  • 大量数据交换:使用共享内存
  • 多个进程协同:使用消息队列或信号灯
相关推荐
java_nnnn3 分钟前
LeetCode刷题滑动窗口(长度最小的子数组)
算法·leetcode·职场和发展
进击的荆棘4 分钟前
Linux系统——库的原理与制作之ELF文件的形成与加载的过程(下)
linux·动静态库
@atweiwei6 分钟前
训练 AI 大模型系列之 LoRA:不动模型本体,靠一条低秩旁路改专长(附完整手算算例)
人工智能·算法·ai·语言模型·rag
小小龙学IT8 分钟前
FFmpeg 开源多媒体处理框架深度解析:从命令行到 libav* 全家桶
c语言·ffmpeg·开源
CrazyMo_13 分钟前
鸿蒙高级——内存专用之linux-reserve-memory 方案简介
linux·运维·服务器
andrsted21 分钟前
练题簿在线免费刷题:Excel、CSV 批量导题与章节整理,把现成表格变成日常题库
学习·微信小程序·小程序·刷题·在线刷题
yi01124 分钟前
DAY27: LeetCode 110. 平衡二叉树 | 在递归中判断是否平衡
人工智能·笔记·python·算法·leetcode·二叉树·递归
灯澜忆梦32 分钟前
【Linux】#5 | 文件与目录基础操作命令
java·linux·运维
96245640 分钟前
餐饮 SaaS 优惠券系统架构演进(七)营销定价引擎设计:活动、会员价、优惠券、买赠如何在同一 PriceQuote 中可解释地组合
java·运维·算法
m0_5474866643 分钟前
《数据结构:基于C语言的描述》全套PPT课件2026
c语言·数据结构