0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux进程间通信(IPC)全解析:从管道到 Socket,一篇讲透

jf_44130326 2025-11-14 21:38 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

Linux世界里,进程并非孤立存在。无论是后台服务协作(如Web服务器与数据库)、命令行工具联动(如ps | grep),还是复杂应用的模块通信,都离不开进程间通信(IPC,Inter-Process Communication)

今天我们就来系统梳理Linux中最常用的6种IPC方式,从原理到实例,从流程到适用场景,帮你彻底搞懂进程间如何“对话”。

一、管道:最简单的“单向传送带”

管道是Linux中最古老的IPC方式,本质是内核中的一块缓冲区,类似“传送带”——数据从一端写入,从另一端读出。

1.匿名管道(Pipe):只认“自家人”

特点

•半双工(数据只能单向流动),需创建两个管道实现双向通信;

•仅用于有亲缘关系的进程(父子、兄弟进程,通过fork继承管道描述符);

•随进程退出自动销毁,不占用磁盘空间。

实例:父子进程用匿名管道聊天

父进程写消息,子进程读消息:

#include#include#includeintmain(){ intpipefd[2]; // 管道描述符:[0]读端,[1]写端 pipe(pipefd); // 创建匿名管道 pid_tpid = fork(); // 创建子进程(继承管道描述符) if(pid ==0) {   // 子进程:读数据   close(pipefd[1]); // 关闭写端(只需要读)   charbuf[100];   read(pipefd[0], buf,sizeof(buf)); // 从管道读   printf("子进程收到:%sn", buf);   close(pipefd[0]);  }else{      // 父进程:写数据   close(pipefd[0]); // 关闭读端(只需要写)   char*msg ="Hi,我是父进程!";   write(pipefd[1], msg,strlen(msg)+1); // 写入管道   close(pipefd[1]);  } return0;}

通信流程

wKgZO2kXJXyAF0XMAAFmOnKhsIs747.png

2.命名管道(FIFO):陌生人也能聊

特点

•与匿名管道功能类似,但通过文件系统中的路径标识(如/tmp/myfifo);

•可用于无亲缘关系的进程(只要知道FIFO路径就能通信);

•是特殊文件(用mkfifo创建),但数据仍存于内存,不落地。

实例:两个独立进程通过FIFO通信

写进程(writer.c):

#include#include#include#includeintmain(){ mkfifo("/tmp/myfifo",0666); // 创建FIFO文件 intfd =open("/tmp/myfifo", O_WRONLY); // 打开写端 char*msg ="来自陌生进程的消息"; write(fd, msg,strlen(msg)+1); close(fd); return0;}

读进程(reader.c):

#include#include#include#includeintmain(){ intfd =open("/tmp/myfifo", O_RDONLY); // 打开读端(会阻塞到有写端打开) charbuf[100]; read(fd, buf,sizeof(buf)); printf("收到:%sn", buf); close(fd); return0;}

通信流程

wKgZO2kXJXyAB2iXAAGA-MuPqdg347.png

二、信号:进程间的“紧急电报”

信号是Linux中最“轻量”的IPC方式,用于通知进程发生了某种事件(如异常、用户指令),类似“紧急电报”。

特点

•异步通信(无需进程主动等待);

•携带信息少(仅一个信号编号);

•内核负责递送(进程可注册处理函数)。

常用信号

•SIGINT(2):用户按Ctrl+C,默认终止进程;

•SIGTERM(15):请求进程终止(默认行为);

•SIGUSR1/SIGUSR2(10/12):用户自定义信号。

实例:进程A给进程B发“自定义电报”

进程B(接收方):

#include#include// 信号处理函数voidhandle_usr1(intsig){ printf("收到SIGUSR1信号!n");}intmain(){ signal(SIGUSR1, handle_usr1); // 注册信号处理函数 printf("我是进程B,PID:%d,等待信号...n",getpid()); while(1); // 无限循环等待 return0;}

进程A(发送方):

#include#includeintmain(){ pid_tb_pid =12345; // 进程B的PID(需替换为实际值) kill(b_pid, SIGUSR1); // 发送SIGUSR1信号给B printf("已发送SIGUSR1给进程%dn", b_pid); return0;}

通信流程

wKgZO2kXJXyAJXitAAFd21mNM-0050.png

三、共享内存:最快的“公共黑板”

共享内存是速度最快的IPC方式——多个进程直接访问同一块物理内存,无需内核“中转”数据。

特点

•无数据拷贝(直接操作内存),效率极高;

•需要同步机制(如信号量)防止“同时写”冲突;

•由内核管理(用shmget创建,shmctl销毁)。

实例:两个进程共享一块内存

写进程(shm_write.c):

#include#include#includeintmain(){ key_tkey =ftok(".",123); // 生成唯一键值 intshmid =shmget(key,1024, IPC_CREAT|0666); // 创建共享内存(大小1024字节) char*shmaddr =shmat(shmid,NULL,0); // 关联到进程地址空间 strcpy(shmaddr,"共享内存中的数据"); // 写入数据 shmdt(shmaddr); // 解除关联 return0;}

读进程(shm_read.c):

#include#includeintmain(){ key_tkey =ftok(".",123); // 相同键值 intshmid =shmget(key,1024,0666); // 获取共享内存 char*shmaddr =shmat(shmid,NULL,0); // 关联到地址空间 printf("读到共享数据:%sn", shmaddr); // 读取数据 shmdt(shmaddr); // 解除关联 shmctl(shmid, IPC_RMID,NULL); // 删除共享内存 return0;}

通信流程

wKgZO2kXJXyAWH-SAAHJn84RCPc718.png

四、消息队列:带“标签”的“邮件箱”

消息队列是内核中的消息链表,每个消息有“类型标签”,进程可按类型接收,类似“带标签的邮件箱”。

特点

•数据有结构(消息类型+数据),支持按类型读取;

•异步通信(发送方无需等待接收方);

•有大小限制(内核参数MSGMAX控制单条消息最大长度)。

实例:按类型发送/接收消息

发送进程(msg_send.c):

#include#include#include// 消息结构(必须以long mtype开头)structmsgbuf{ longmtype; // 消息类型(正数) charmtext[100]; // 消息内容};intmain(){ key_tkey =ftok(".",456); intmsqid =msgget(key, IPC_CREAT|0666); // 创建消息队列 structmsgbufmsg;  msg.mtype =1; // 类型为1 strcpy(msg.mtext,"类型1的消息"); msgsnd(msqid, &msg,sizeof(msg.mtext),0); // 发送消息 return0;}

接收进程(msg_recv.c):

#include#includestructmsgbuf{ longmtype; charmtext[100];};intmain(){ key_tkey =ftok(".",456); intmsqid =msgget(key,0666); // 获取消息队列 structmsgbufmsg; msgrcv(msqid, &msg,sizeof(msg.mtext),1,0); // 只接收类型1的消息 printf("收到类型%d的消息:%sn", msg.mtype, msg.mtext); msgctl(msqid, IPC_RMID,NULL); // 删除消息队列 return0;}

通信流程

wKgZO2kXJX2AemTTAAH-Chbfbrg478.png

五、信号量:进程同步的“红绿灯”

信号量不是用于传递数据,而是控制多个进程对共享资源的访问(如共享内存、文件),类似“红绿灯”。

核心概念

•信号量值(semaphore):>=0的整数,代表“可用资源数”;

•P操作(等待):信号量值- 1,若值< 0 则阻塞;

•V操作(释放):信号量值+ 1,若有进程阻塞则唤醒。

实例:用信号量保护共享内存

(基于共享内存,添加信号量控制):

#include// 定义P/V操作(简化版)voidP(intsemid){ structsembufs = {0,-1,0}; // 第0个信号量,-1(P操作) semop(semid, &s,1);}voidV(intsemid){ structsembufs = {0,1,0}; // +1(V操作) semop(semid, &s,1);}// 初始化信号量(值为1,代表互斥)intinit_sem(){ key_tkey =ftok(".",789); intsemid =semget(key,1, IPC_CREAT|0666); semctl(semid,0, SETVAL,1); // 第0个信号量值设为1 returnsemid;}// 写进程在访问共享内存前P,写完V;读进程同理

同步流程

wKgZO2kXJX2AIGuDAAG5yFL1gdY006.png

六、Socket:跨主机通信的“万能接口

Socket(套接字)是最灵活的IPC方式,不仅支持同一主机的进程通信,还能跨网络(如服务器与客户端)。

特点

•支持TCP(可靠、面向连接)和UDP(不可靠、无连接);

•本地通信可用AF_UNIX协议(通过文件路径标识);

网络通信用AF_INET协议(通过IP +端口标识)。

实例:本地Socket通信(AF_UNIX)

服务器(sock_server.c):

#include#include#include#include#includeintmain(){ intsockfd =socket(AF_UNIX, SOCK_STREAM,0); // 创建本地套接字 structsockaddr_unaddr;  addr.sun_family = AF_UNIX; strcpy(addr.sun_path,"/tmp/mysock"); // 本地路径 bind(sockfd, (structsockaddr*)&addr,sizeof(addr)); // 绑定 listen(sockfd,5); // 监听 intconnfd =accept(sockfd,NULL,NULL); // 接受连接 charbuf[100]; read(connfd, buf,sizeof(buf)); printf("收到:%sn", buf); close(connfd); close(sockfd); unlink("/tmp/mysock"); // 删除套接字文件 return0;}

客户端(sock_client.c):

#include#include#include#include#includeintmain(){ intsockfd =socket(AF_UNIX, SOCK_STREAM,0); structsockaddr_unaddr;  addr.sun_family = AF_UNIX; strcpy(addr.sun_path,"/tmp/mysock"); connect(sockfd, (structsockaddr*)&addr,sizeof(addr)); // 连接服务器 char*msg ="本地Socket消息"; write(sockfd, msg,strlen(msg)+1); close(sockfd); return0;}

通信流程

wKgZO2kXJX2AGrT1AAFrtXkKlrQ220.png

总结:如何选择合适的IPC方式?

方式 速度 复杂度 适用场景
匿名管道 父子进程简单单向通信
命名管道 无亲缘关系进程简单通信
信号 快(异步) 事件通知(如异常、退出)
共享内存 最快 高(需同步) 高频、大数据量共享
消息队列 需按类型传递消息的场景
信号量 进程同步与互斥(配合其他IPC)
Socket 较慢 跨主机或复杂通信(如网络服务)

进程间通信是Linux开发的核心基础,理解每种方式的优缺点,才能在实际场景中“对症下药”。比如日志收集可用命名管道,实时数据共享用共享内存+信号量,网络服务则离不开Socket。

你在开发中用过哪种IPC方式?遇到过哪些坑?欢迎在评论区交流~

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    88

    文章

    11627

    浏览量

    217887
  • IPC
    IPC
    +关注

    关注

    3

    文章

    375

    浏览量

    54540
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux进程通信方式-管道

    Linux进程通信方式-管道分享: 本文关键字: l
    发表于 08-29 15:29

    Linux学习杂谈】之进程通信

    我们详细看下进程通信大致分为以下几个方面: Linux进程
    发表于 10-15 14:45

    进程通信之:管道

    | grep ntp为例,描述管道通信过程,如图8.2所示。 图8.2 管道通信过程 管道Lin
    发表于 10-18 16:06 0次下载
    <b class='flag-5'>进程</b><b class='flag-5'>间</b><b class='flag-5'>通信</b>之:<b class='flag-5'>管道</b>

    Linux进程通信

    进程通信IPC)以下以几部分发展而来:早期UNIX进程
    发表于 04-02 14:46 653次阅读

    Linux进程通信方式——管道

    管道Linux进程通信种方式,它把个程序
    发表于 06-01 09:13 1748次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>进程</b><b class='flag-5'>间</b><b class='flag-5'>通信</b>方式——<b class='flag-5'>管道</b>

    嵌入式Linux进程 -进程通信

    最常用的无名管道,有名管道,消息队列,信号,信号量,共享内存等进程通信方式。其实后面网络通信
    发表于 11-01 17:20 9次下载
    嵌入式<b class='flag-5'>Linux</b><b class='flag-5'>进程</b> -<b class='flag-5'>进程</b><b class='flag-5'>间</b><b class='flag-5'>通信</b>

    Linux进程通信方法之管道

    上文中我们介绍了进程通信的方法之:信号,本文将继续介绍另进程
    的头像 发表于 05-14 15:47 2599次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>进程</b><b class='flag-5'>间</b><b class='flag-5'>通信</b>方法之<b class='flag-5'>管道</b>

    Linux进程的五种通信方式介绍 1

    进程通信IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。
    的头像 发表于 02-15 10:18 1896次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>进程</b><b class='flag-5'>间</b>的五种<b class='flag-5'>通信</b>方式介绍 1

    Linux进程的五种通信方式介绍 2

    进程通信IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。
    的头像 发表于 02-15 10:19 943次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>进程</b><b class='flag-5'>间</b>的五种<b class='flag-5'>通信</b>方式介绍 2

    Linux进程的五种通信方式介绍 3

    进程通信IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。
    的头像 发表于 02-15 10:19 896次阅读

    Linux进程的五种通信方式介绍 4

    进程通信IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。
    的头像 发表于 02-15 10:19 1075次阅读

    Linux进程的五种通信方式介绍 6

    进程通信IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。
    的头像 发表于 02-15 10:19 840次阅读

    Linux进程的五种通信方式介绍 5

    进程通信IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。
    的头像 发表于 02-15 10:20 974次阅读

    如何实现linux进程通信的机制

    我们知道linux进程通信的组件有管道,消息队列,socket, 信号量,共享内存等。但是
    的头像 发表于 11-10 14:56 1087次阅读
    如何实现<b class='flag-5'>一</b>套<b class='flag-5'>linux</b><b class='flag-5'>进程</b><b class='flag-5'>间</b><b class='flag-5'>通信</b>的机制

    linux管道概述

    进程通信IPC)介绍 进程
    的头像 发表于 02-18 14:51 951次阅读
    <b class='flag-5'>linux</b><b class='flag-5'>管道</b>概述