91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

Linux進程間通信(IPC)全解析:從管道到?Socket,一篇講透

jf_44130326 ? 2025-11-14 21:38 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Linux世界里,進程并非孤立存在。無論是后臺服務協(xié)作(如Web服務器與數(shù)據(jù)庫)、命令行工具聯(lián)動(如ps | grep),還是復雜應用的模塊通信,都離不開進程間通信(IPC,Inter-Process Communication)。

今天我們就來系統(tǒng)梳理Linux中最常用的6種IPC方式,從原理到實例,從流程到適用場景,幫你徹底搞懂進程間如何“對話”。

一、管道:最簡單的“單向傳送帶”

管道是Linux中最古老的IPC方式,本質(zhì)是內(nèi)核中的一塊緩沖區(qū),類似“傳送帶”——數(shù)據(jù)從一端寫入,從另一端讀出。

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

特點

?半雙工(數(shù)據(jù)只能單向流動),需創(chuàng)建兩個管道實現(xiàn)雙向通信;

?僅用于有親緣關系的進程(父子、兄弟進程,通過fork繼承管道描述符);

?隨進程退出自動銷毀,不占用磁盤空間。

實例:父子進程用匿名管道聊天

父進程寫消息,子進程讀消息:

#include#include#includeintmain(){ intpipefd[2]; // 管道描述符:[0]讀端,[1]寫端 pipe(pipefd); // 創(chuàng)建匿名管道 pid_tpid = fork(); // 創(chuàng)建子進程(繼承管道描述符) if(pid ==0) {   // 子進程:讀數(shù)據(jù)   close(pipefd[1]); // 關閉寫端(只需要讀)   charbuf[100];   read(pipefd[0], buf,sizeof(buf)); // 從管道讀   printf("子進程收到:%sn", buf);   close(pipefd[0]);  }else{      // 父進程:寫數(shù)據(jù)   close(pipefd[0]); // 關閉讀端(只需要寫)   char*msg ="Hi,我是父進程!";   write(pipefd[1], msg,strlen(msg)+1); // 寫入管道   close(pipefd[1]);  } return0;}

通信流程

wKgZO2kXJXyAF0XMAAFmOnKhsIs747.png

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

特點

?與匿名管道功能類似,但通過文件系統(tǒng)中的路徑標識(如/tmp/myfifo);

?可用于無親緣關系的進程(只要知道FIFO路徑就能通信);

?是特殊文件(用mkfifo創(chuàng)建),但數(shù)據(jù)仍存于內(nèi)存,不落地。

實例:兩個獨立進程通過FIFO通信

寫進程(writer.c):

#include#include#include#includeintmain(){ mkfifo("/tmp/myfifo",0666); // 創(chuàng)建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方式,用于通知進程發(fā)生了某種事件(如異常、用戶指令),類似“緊急電報”。

特點

?異步通信(無需進程主動等待);

?攜帶信息少(僅一個信號編號);

?內(nèi)核負責遞送(進程可注冊處理函數(shù))。

常用信號

?SIGINT(2):用戶按Ctrl+C,默認終止進程;

?SIGTERM(15):請求進程終止(默認行為);

?SIGUSR1/SIGUSR2(10/12):用戶自定義信號。

實例:進程A給進程B發(fā)“自定義電報”

進程B(接收方):

#include#include// 信號處理函數(shù)voidhandle_usr1(intsig){ printf("收到SIGUSR1信號!n");}intmain(){ signal(SIGUSR1, handle_usr1); // 注冊信號處理函數(shù) printf("我是進程B,PID:%d,等待信號...n",getpid()); while(1); // 無限循環(huán)等待 return0;}

進程A(發(fā)送方):

#include#includeintmain(){ pid_tb_pid =12345; // 進程B的PID(需替換為實際值) kill(b_pid, SIGUSR1); // 發(fā)送SIGUSR1信號給B printf("已發(fā)送SIGUSR1給進程%dn", b_pid); return0;}

通信流程

wKgZO2kXJXyAJXitAAFd21mNM-0050.png

三、共享內(nèi)存:最快的“公共黑板”

共享內(nèi)存是速度最快的IPC方式——多個進程直接訪問同一塊物理內(nèi)存,無需內(nèi)核“中轉(zhuǎn)”數(shù)據(jù)。

特點

?無數(shù)據(jù)拷貝(直接操作內(nèi)存),效率極高;

?需要同步機制(如信號量)防止“同時寫”沖突;

?由內(nèi)核管理(用shmget創(chuàng)建,shmctl銷毀)。

實例:兩個進程共享一塊內(nèi)存

寫進程(shm_write.c):

#include#include#includeintmain(){ key_tkey =ftok(".",123); // 生成唯一鍵值 intshmid =shmget(key,1024, IPC_CREAT|0666); // 創(chuàng)建共享內(nèi)存(大小1024字節(jié)) char*shmaddr =shmat(shmid,NULL,0); // 關聯(lián)到進程地址空間 strcpy(shmaddr,"共享內(nèi)存中的數(shù)據(jù)"); // 寫入數(shù)據(jù) shmdt(shmaddr); // 解除關聯(lián) return0;}

讀進程(shm_read.c):

#include#includeintmain(){ key_tkey =ftok(".",123); // 相同鍵值 intshmid =shmget(key,1024,0666); // 獲取共享內(nèi)存 char*shmaddr =shmat(shmid,NULL,0); // 關聯(lián)到地址空間 printf("讀到共享數(shù)據(jù):%sn", shmaddr); // 讀取數(shù)據(jù) shmdt(shmaddr); // 解除關聯(lián) shmctl(shmid, IPC_RMID,NULL); // 刪除共享內(nèi)存 return0;}

通信流程

wKgZO2kXJXyAWH-SAAHJn84RCPc718.png

四、消息隊列:帶“標簽”的“郵件箱”

消息隊列是內(nèi)核中的消息鏈表,每個消息有“類型標簽”,進程可按類型接收,類似“帶標簽的郵件箱”。

特點

?數(shù)據(jù)有結構(消息類型+數(shù)據(jù)),支持按類型讀??;

?異步通信(發(fā)送方無需等待接收方);

?有大小限制(內(nèi)核參數(shù)MSGMAX控制單條消息最大長度)。

實例:按類型發(fā)送/接收消息

發(fā)送進程(msg_send.c):

#include#include#include// 消息結構(必須以long mtype開頭)structmsgbuf{ longmtype; // 消息類型(正數(shù)) charmtext[100]; // 消息內(nèi)容};intmain(){ key_tkey =ftok(".",456); intmsqid =msgget(key, IPC_CREAT|0666); // 創(chuàng)建消息隊列 structmsgbufmsg;  msg.mtype =1; // 類型為1 strcpy(msg.mtext,"類型1的消息"); msgsnd(msqid, &msg,sizeof(msg.mtext),0); // 發(fā)送消息 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

五、信號量:進程同步的“紅綠燈”

信號量不是用于傳遞數(shù)據(jù),而是控制多個進程對共享資源的訪問(如共享內(nèi)存、文件),類似“紅綠燈”。

核心概念

?信號量值(semaphore):>=0的整數(shù),代表“可用資源數(shù)”;

?P操作(等待):信號量值- 1,若值< 0?則阻塞;

?V操作(釋放):信號量值+ 1,若有進程阻塞則喚醒。

實例:用信號量保護共享內(nèi)存

(基于共享內(nèi)存,添加信號量控制):

#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;}// 寫進程在訪問共享內(nèi)存前P,寫完V;讀進程同理

同步流程

wKgZO2kXJX2AIGuDAAG5yFL1gdY006.png

六、Socket:跨主機通信的“萬能接口

Socket(套接字)是最靈活的IPC方式,不僅支持同一主機的進程通信,還能跨網(wǎng)絡(如服務器與客戶端)。

特點

?支持TCP(可靠、面向連接)和UDP(不可靠、無連接);

?本地通信可用AF_UNIX協(xié)議(通過文件路徑標識);

?網(wǎng)絡通信用AF_INET協(xié)議(通過IP +端口標識)。

實例:本地Socket通信(AF_UNIX)

服務器(sock_server.c):

#include#include#include#include#includeintmain(){ intsockfd =socket(AF_UNIX, SOCK_STREAM,0); // 創(chuàng)建本地套接字 structsockaddr_unaddr;  addr.sun_family = AF_UNIX; strcpy(addr.sun_path,"/tmp/mysock"); // 本地路徑 bind(sockfd, (structsockaddr*)&addr,sizeof(addr)); // 綁定 listen(sockfd,5); // 監(jiān)聽 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方式?

方式 速度 復雜度 適用場景
匿名管道 父子進程簡單單向通信
命名管道 無親緣關系進程簡單通信
信號 快(異步) 事件通知(如異常、退出)
共享內(nèi)存 最快 高(需同步) 高頻、大數(shù)據(jù)量共享
消息隊列 需按類型傳遞消息的場景
信號量 進程同步與互斥(配合其他IPC)
Socket 較慢 跨主機或復雜通信(如網(wǎng)絡服務)

進程間通信是Linux開發(fā)的核心基礎,理解每種方式的優(yōu)缺點,才能在實際場景中“對癥下藥”。比如日志收集可用命名管道,實時數(shù)據(jù)共享用共享內(nèi)存+信號量,網(wǎng)絡服務則離不開Socket。

你在開發(fā)中用過哪種IPC方式?遇到過哪些坑?歡迎在評論區(qū)交流~

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    88

    文章

    11755

    瀏覽量

    218995
  • IPC
    IPC
    +關注

    關注

    3

    文章

    378

    瀏覽量

    54874
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    Linux進程通信方式-管道

    Linux進程通信方式-管道分享: 本文關鍵字: l
    發(fā)表于 08-29 15:29

    Linux學習雜談】之進程通信

    我們詳細看下進程通信大致分為以下幾個方面: Linux進程
    發(fā)表于 10-15 14:45

    進程通信之:管道

    | grep ntp為例,描述管道通信過程,如圖8.2所示。 圖8.2 管道通信過程 管道Lin
    發(fā)表于 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)以下以幾部分發(fā)展而來:早期UNIX進程
    發(fā)表于 04-02 14:46 ?715次閱讀

    Linux進程通信方式——管道

    管道Linux進程通信種方式,它把個程序
    發(fā)表于 06-01 09:13 ?1823次閱讀
    <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進程 -進程通信

    最常用的無名管道,有名管道,消息隊列,信號,信號量,共享內(nèi)存等進程通信方式。其實后面網(wǎng)絡通信
    發(fā)表于 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進程通信方法之管道

    上文中我們介紹了進程通信的方法之:信號,本文將繼續(xù)介紹另進程
    的頭像 發(fā)表于 05-14 15:47 ?2907次閱讀
    <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)是指在不同進程之間傳播或交換信息。
    的頭像 發(fā)表于 02-15 10:18 ?2033次閱讀
    <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)是指在不同進程之間傳播或交換信息。
    的頭像 發(fā)表于 02-15 10:19 ?1093次閱讀
    <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)是指在不同進程之間傳播或交換信息。
    的頭像 發(fā)表于 02-15 10:19 ?1018次閱讀

    Linux進程的五種通信方式介紹 4

    進程通信IPC,InterProcess Communication)是指在不同進程之間傳播或交換信息。
    的頭像 發(fā)表于 02-15 10:19 ?1205次閱讀

    Linux進程的五種通信方式介紹 6

    進程通信IPC,InterProcess Communication)是指在不同進程之間傳播或交換信息。
    的頭像 發(fā)表于 02-15 10:19 ?991次閱讀

    Linux進程的五種通信方式介紹 5

    進程通信IPC,InterProcess Communication)是指在不同進程之間傳播或交換信息。
    的頭像 發(fā)表于 02-15 10:20 ?1086次閱讀

    如何實現(xiàn)linux進程通信的機制

    我們知道linux進程通信的組件有管道,消息隊列,socket, 信號量,共享內(nèi)存等。但是
    的頭像 發(fā)表于 11-10 14:56 ?1222次閱讀
    如何實現(xiàn)<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)介紹 進程
    的頭像 發(fā)表于 02-18 14:51 ?1140次閱讀
    <b class='flag-5'>linux</b><b class='flag-5'>管道</b>概述