您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center 汽车系统工程   模型库  
会员   
   
基于UML和EA进行分析设计
2月3-4日 北京+线上
需求分析与管理
2月9-10日 北京+线上
AI大模型编写高质量代码
3月12-13日 北京+线上
     
   
 订阅
进程间通信(IPC)机制详解
 
作者:Rare-30
  219   次浏览      6 次
 2026-1-20
 
编辑推荐:
本文介绍了五种常用的IPC方式:管道、信号、共享内存、消息队列和信号量,并附上相关函数的用法示例。 希望能为大家提供一些参考或帮助。
文章来自于博客园,由火龙果Linda编辑推荐。

在操作系统中,进程间通信(Inter-Process Communication, IPC)是不同进程间交换数据与同步操作的机制。本文将详细讲解五种常用的IPC方式:管道、信号、共享内存、消息队列和信号量,并附上相关函数的用法示例。

1. 管道(Pipe)

管道是Unix/Linux中最古老的IPC形式,分为匿名管道和命名管道两种。

匿名管道

#include <unistd.h>
int pipe(int pipefd[2]);

  • pipefd[0]: 读端

  • pipefd[1]: 写端

  • 返回值:成功返回0,失败返回-1

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main() {
    int pipefd[2];
    char buf[20];

    if (pipe(pipefd) == -1) {
        perror("pipe");
        return 1;
    }

     pid_t pid = fork();
    if (pid == 0) { // 子进程
        close(pipefd[0]); // 关闭读端
        write(pipefd[1], "Hello, Parent!", 14);
        close(pipefd[1]);
    } else { // 父进程
        close(pipefd[1]); // 关闭写端
        read(pipefd[0], buf, sizeof(buf));
        printf("Parent received: %s\n", buf);
        close(pipefd[0]);
        wait(NULL);
    }
    return 0;
}

命名管道(FIFO)

#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);

  • 创建命名管道文件

  • mode参数指定文件权限

使用流程:

    1.创建FIFO:mkfifo("/tmp/myfifo", 0666)

    2.进程A:open("/tmp/myfifo", O_WRONLY) 并写入数据

    3.进程B:open("/tmp/myfifo", O_RDONLY) 并读取数据

2. 信号(Signal)

信号是异步通信机制,用于通知进程发生了某个事件。

常用函数

#include <signal.h>
void (*signal(int signum, void (*handler)(int)))(int);
int kill(pid_t pid, int sig);
int raise(int sig);
unsigned int alarm(unsigned int seconds);

常见信号:

  • SIGINT (2): 终端中断(Ctrl+C)

  • SIGKILL (9): 强制终止

  • SIGSEGV (11): 段错误

  • SIGALRM (14): 定时器信号

示例代码:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void handler(int sig) {
    printf("Received signal: %d\n", sig);
}

int main() {
    signal(SIGINT, handler); // 注册SIGINT处理函数
    signal(SIGALRM, handler); // 注册SIGALRM处理函数

    alarm(3); // 3秒后发送SIGALRM

    while(1) {
        pause(); // 等待信号
    }
    return 0;
}

3. 共享内存(Shared Memory)

共享内存允许多个进程访问同一块内存区域,是最快的IPC方式。

关键函数

#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

使用步骤:

    1.创建/获取共享内存段:shmget()

    2.附加到进程地址空间:shmat()

    3.读写共享内存

    4.分离共享内存:shmdt()

    5.控制共享内存(删除等):shmctl()

示例代码:

#include <stdio.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <string.h>

#define SHM_SIZE 1024

int main() {
    key_t key = ftok("/tmp", 'A');
    int shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666);

    if (shmid == -1) {
        perror("shmget");
        return 1;
    }

    char *shm_ptr = (char*)shmat(shmid, NULL, 0);
    if (shm_ptr == (void*)-1) {
        perror("shmat");
        return 1;
    }

    // 写入数据
    strcpy(shm_ptr, "Hello, Shared Memory!");

    // 读取数据(在另一个进程中)
    // printf("Read from shared memory: %s\n", shm_ptr);

    shmdt(shm_ptr);
    shmctl(shmid, IPC_RMID, NULL); // 删除共享内存
    return 0;
}

4. 消息队列(Message Queue)

消息队列允许进程通过发送/接收消息来通信。

关键函数

#include <sys/msg.h>
int msgget(key_t key, int msgflg);
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
int msgctl(int msqid, int cmd, struct msqid_ds *buf);

消息结构:

struct msgbuf {
    long mtype; // 消息类型
    char mtext[1]; // 消息数据
};

示例代码:

#include <stdio.h>
#include <sys/msg.h>
#include <string.h>

struct msgbuf {
    long mtype;
    char mtext[100];
};

int main() {
    key_t key = ftok("/tmp", 'B');
    int msgid = msgget(key, IPC_CREAT | 0666);

    struct msgbuf msg;
    msg.mtype = 1;
    strcpy(msg.mtext, "Hello, Message Queue!");

    // 发送消息
    if (msgsnd(msgid, &msg, sizeof(msg.mtext), 0) == -1) {
        perror("msgsnd");
        return 1;
    }

    // 接收消息(在另一个进程中)
    // if (msgrcv(msgid, &msg, sizeof(msg.mtext), 1, 0) == -1) {
    // perror("msgrcv");
    // return 1;
    // }
// printf("Received: %s\n", msg.mtext);

    msgctl(msgid, IPC_RMID, NULL); // 删除消息队列
    return 0;
}

5. 信号量(Semaphore)

信号量用于进程间的同步,控制对共享资源的访问。

关键函数

#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
int semop(int semid, struct sembuf *sops, unsigned nsops);
int semctl(int semid, int semnum, int cmd, ...);

操作结构体:

struct sembuf {
    unsigned short sem_num; // 信号量编号
    short sem_op; // 操作(正数加,负数减)
    short sem_flg; // 标志(通常为0)
};

示例代码:

#include <stdio.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <unistd.h>

union semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};

int main() {
     key_t key = ftok("/tmp", 'C');
    int semid = semget(key, 1, IPC_CREAT | 0666);

     union semun arg;
    arg.val = 1; // 初始值设为1(二进制信号量)
    semctl(semid, 0, SETVAL, arg);

    struct sembuf op_lock = {0, -1, 0}; // P操作
    struct sembuf op_unlock = {0, 1, 0}; // V操作

    // 加锁
    semop(semid, &op_lock, 1);

    printf("Critical section start\n");
    sleep(2); // 模拟临界区操作
    printf("Critical section end\n");

    // 解锁
    semop(semid, &op_unlock, 1);

    semctl(semid, 0, IPC_RMID); // 删除信号量
    return 0;
}

IPC方式对比

机制 速度 复杂度 适用场景
管道 中等 父子进程间简单通信
命名管道 中等 任意进程间流式通信
信号 事件通知、简单控制
共享内存 最快 大数据量、高性能通信
消息队列 中高 结构化的进程间通信
信号量 进程同步、资源访问控制

总结

不同的IPC机制适用于不同的场景:

  • 管道/命名管道:适合流式数据传输

  • 信号:适合事件通知和简单控制

  • 共享内存:适合高性能大数据传输

  • 消息队列:适合结构化消息传递

  • 信号量:适合进程同步和资源保护

在实际系统编程中,通常需要组合多种IPC机制来满足复杂需求。理解各种IPC机制的特点和使用场景,能够帮助开发者设计出高效可靠的进程间通信方案。

 

   
219   次浏览       6 次
相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程

最新活动计划
AI大模型编写高质量代码 2-9[在线]
基于UML+EA进行分析设计 2-3[北京]
需求分析与管理 2-9[北京]
基于模型的数据治理 3-10[北京]
UAF与企业架构 2-3[北京]
ASPICE4.0核心开发过程 3-21[上海]
嵌入式软件测试 3-27[上海]
 
 
最新文章
.NET Core 3.0 正式公布:新特性详细解读
.NET Core部署中你不了解的框架依赖与独立部署
C# event线程安全
简析 .NET Core 构成体系
C#技术漫谈之垃圾回收机制(GC)
最新课程
.Net应用开发
C#高级开发技术
.NET 架构设计与调试优化
ASP.NET Core Web 开发
ASP.Net MVC框架原理与应用开发
成功案例
航天科工集团子公司 DotNet企业级应用设计与开发
日照港集 .NET Framewor
神华信 .NET单元测试
台达电子 .NET程序设计与开发
神华信息 .NET单元测试