管道用于父子进程通信,如匿名管道传递”Hello from child!”;2. 共享内存通过shm_open和mmap实现高效数据共享;3. 消息队列用mq_send发送”Test message”实现异步通信;4. 信号量sem_wait与sem_post保证临界区互斥;5. unix域套接字通过AF_UNIX实现本地进程通信。

在c++中进行进程间通信(IPC)有多种方式,适用于不同场景,比如数据共享、同步控制或跨进程调用。下面介绍几种常见的IPC机制及其使用示例,帮助你根据需求选择合适的方法。
1. 管道(Pipe)
管道是最基本的IPC方式之一,分为匿名管道和命名管道。匿名管道通常用于父子进程之间通信,而命名管道可在不相关的进程间使用。
匿名管道示例(父子进程):
#include <iostream> #include <unistd.h> #include <sys/wait.h> #include <string> <p>int main() { int pipefd[2]; pid_t pid; const std::string msg = "Hello from child!";</p><pre class='brush:php;toolbar:false;'>if (pipe(pipefd) == -1) { perror("pipe"); return 1; } pid = fork(); if (pid == 0) { // 子进程 close(pipefd[0]); // 关闭读端 write(pipefd[1], msg.c_str(), msg.length()); close(pipefd[1]); } else { // 父进程 close(pipefd[1]); // 关闭写端 char buffer[128] = {0}; read(pipefd[0], buffer, sizeof(buffer)); std::cout << "Received: " << buffer << std::endl; close(pipefd[0]); wait(NULL); } return 0;
}
立即学习“C++免费学习笔记(深入)”;
编译运行需在linux/Unix环境下,使用g++并链接标准库。
2. 共享内存(Shared Memory)
共享内存是最快的IPC方式,多个进程可访问同一块内存区域。需配合信号量等机制实现同步。
使用POSIX共享内存示例:
#include <iostream> #include <fcntl.h> #include <sys/mman.h> #include <unistd.h> #include <cstring> <p>int main() { const char<em> name = "/my_shm"; const int SIZE = 4096; int shm_fd; char</em> ptr;</p><pre class='brush:php;toolbar:false;'>shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666); ftruncate(shm_fd, SIZE); ptr = (char*)mmap(0, SIZE, PROT_WRITE, MAP_SHAred, shm_fd, 0); std::strcpy(ptr, "Message via shared memory"); // 读取方稍后读取 sleep(2); // 模拟等待另一进程读取 shm_unlink(name); return 0;
}
立即学习“C++免费学习笔记(深入)”;
另一个进程可用相同名称打开并读取该内存段。
3. 消息队列(Message Queue)
消息队列允许进程通过结构化消息传递数据,支持异步通信。
POSIX消息队列示例:
#include <mqueue.h> #include <fcntl.h> #include <sys/stat.h> #include <iostream> #include <cstring> <p>int main() { mqd_t mq; struct mq_attr attr; const char* msg = "Test message";</p><pre class='brush:php;toolbar:false;'>attr.mq_flags = 0; attr.mq_maxmsg = 10; attr.mq_msgsize = 256; attr.mq_curmsgs = 0; mq = mq_open("/test_queue", O_CREAT | O_WRONLY, 0666, &attr); mq_send(mq, msg, strlen(msg), 1); mq_close(mq); return 0;
}
立即学习“C++免费学习笔记(深入)”;
接收进程使用O_RDONLY打开并调用mq_receive读取消息。
4. 信号量(Semaphore)
信号量用于进程间的同步,防止多个进程同时访问共享资源。
POSIX命名信号量示例:
#include <semaphore.h> #include <fcntl.h> #include <iostream> #include <unistd.h> <p>int main() { sem_t* sem = sem_open("/my_sem", O_CREAT, 0666, 1);</p><pre class='brush:php;toolbar:false;'>sem_wait(sem); // 获取锁 std::cout << "Process in critical section" << std::endl; sleep(2); sem_post(sem); // 释放锁 sem_close(sem); sem_unlink("/my_sem"); return 0;
}
立即学习“C++免费学习笔记(深入)”;
多个进程可通过同一名称访问该信号量实现互斥。
5. 套接字(Socket)
套接字不仅可用于网络通信,也可用于本地进程通信(Unix域套接字),灵活性高。
Unix域数据报套接字示例(服务端):
#include <sys/socket.h> #include <sys/un.h> #include <iostream> #include <unistd.h> <p>int main() { int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0); struct sockaddr_un addr; std::memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; std::strcpy(addr.sun_path, "/tmp/socket");</p><pre class='brush:php;toolbar:false;'>bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)); char buffer[256]; recvfrom(sockfd, buffer, sizeof(buffer), 0, nullptr, nullptr); std::cout << "Received: " << buffer << std::endl; close(sockfd); unlink("/tmp/socket"); return 0;
}
立即学习“C++免费学习笔记(深入)”;
客户端创建同样类型的套接字并发送消息到该路径。
基本上就这些常见方式。选择哪种取决于你的平台、性能要求和通信模式。管道简单但限制多,共享内存高效但需注意同步,套接字最灵活适合复杂系统。实际开发中常组合使用,比如共享内存+信号量来兼顾速度与安全。


