小浪底水利枢纽建设管理局网站,网站建设流程步骤为需求分析,上海十大保安公司排名,家装设计费用多少钱一平方在C中#xff0c;进程间通信#xff08;IPC#xff09;是让多个独立进程交换数据和协调操作的机制。以下详细介绍三种常见的IPC方式#xff1a;
一、管道#xff08;Pipes#xff09;
管道是一种半双工的通信方式#xff0c;数据只能单向流动#xff0c;分为匿名管道…在C中进程间通信IPC是让多个独立进程交换数据和协调操作的机制。以下详细介绍三种常见的IPC方式
一、管道Pipes
管道是一种半双工的通信方式数据只能单向流动分为匿名管道和命名管道。
匿名管道Anonymous Pipes
特点 只能用于父子进程或兄弟进程之间具有亲缘关系的进程。单向通信一端读一端写。生命周期随进程结束而销毁。 原理 通过系统调用pipe(int fd[2])创建返回两个文件描述符fd[0]读端和fd[1]写端。数据写入管道后存储在内核缓冲区读取后即被移除。 示例代码父子进程通信
#include unistd.h
#include iostreamint main() {int fd[2];char buffer[100];if (pipe(fd) -1) {perror(pipe failed);return 1;}pid_t pid fork();if (pid 0) {perror(fork failed);return 1;}if (pid 0) { // 子进程写数据close(fd[0]); // 关闭读端const char* msg Hello from child!;write(fd[1], msg, strlen(msg) 1);close(fd[1]);} else { // 父进程读数据close(fd[1]); // 关闭写端read(fd[0], buffer, sizeof(buffer));std::cout Parent received: buffer std::endl;close(fd[0]);}return 0;
}命名管道Named Pipes/FIFOs
特点 以文件形式存在通过mkfifo创建可用于无亲缘关系的进程。遵循先进先出FIFO原则。进程通过打开文件进行读写。 示例代码
// 写进程
#include fcntl.h
#include unistd.hint main() {int fd open(myfifo, O_WRONLY);write(fd, Hello from writer!, 18);close(fd);return 0;
}// 读进程
#include fcntl.h
#include iostream
#include unistd.hint main() {int fd open(myfifo, O_RDONLY);char buffer[100];read(fd, buffer, 100);std::cout Reader received: buffer std::endl;close(fd);return 0;
}注意需先创建FIFO文件mkfifo myfifo。
二、 共享内存Shared Memory
共享内存允许多个进程直接访问同一块物理内存是最快的IPC方式。
特点
高效数据无需复制直接通过指针访问。需同步需配合信号量或互斥锁避免竞态条件。生命周期独立于进程需手动删除。
原理
创建共享内存段shmget。将其映射到进程的地址空间shmat。进程读写内存操作完成后解除映射shmdt并删除shmctl。
示例代码
#include sys/ipc.h
#include sys/shm.h
#include iostream
#include cstringint main() {// 创建共享内存段键值为1234大小1024字节int shmid shmget(1234, 1024, 0666 | IPC_CREAT);if (shmid -1) {perror(shmget failed);return 1;}// 映射到当前进程char* shared_memory (char*)shmat(shmid, nullptr, 0);if (shared_memory (char*)-1) {perror(shmat failed);return 1;}// 写入数据std::strcpy(shared_memory, Hello from shared memory!);// 解除映射if (shmdt(shared_memory) -1) {perror(shmdt failed);return 1;}// 读取数据的进程类似只需将写入操作改为读取return 0;
}三、 消息队列Message Queues
消息队列是内核管理的链表进程通过发送/接收消息进行通信。
特点
异步通信发送方和接收方无需同时运行。消息类型消息可按类型分类接收方可选定类型接收。持久化消息会一直存在直到被读取或队列被删除。
原理
创建消息队列msgget。发送消息msgsnd和接收消息msgrcv。删除队列msgctl。
示例代码
#include sys/msg.h
#include iostream
#include cstringstruct Message {long mtype; // 消息类型必须大于0char mtext[100]; // 消息内容
};int main() {// 创建消息队列键值为5678int msgid msgget(5678, 0666 | IPC_CREAT);if (msgid -1) {perror(msgget failed);return 1;}// 发送消息Message msg;msg.mtype 1;std::strcpy(msg.mtext, Hello from message queue!);if (msgsnd(msgid, msg, sizeof(msg.mtext), 0) -1) {perror(msgsnd failed);return 1;}// 接收消息Message received;if (msgrcv(msgid, received, sizeof(received.mtext), 1, 0) -1) {perror(msgrcv failed);return 1;}std::cout Received: received.mtext std::endl;// 删除队列if (msgctl(msgid, IPC_RMID, nullptr) -1) {perror(msgctl failed);return 1;}return 0;
}对比与选择
方式优点缺点适用场景管道简单易用自动同步单向容量有限父子进程间少量数据传输共享内存速度最快适合大量数据需手动同步管理复杂高性能计算图形处理消息队列异步通信按类型分类效率低于共享内存分布式系统事件驱动架构
注意事项
同步问题共享内存和管道需注意竞态条件建议配合信号量或互斥锁使用。资源释放共享内存和消息队列需手动删除避免内存泄漏。平台差异Windows和Linux的IPC实现有所不同上述示例适用于POSIX系统。