c++ 进程通信
时间: 2025-05-17 15:18:39 浏览: 8
### C++ 进程间通信方法及其实现
#### 方法一:消息队列
消息队列是一种可靠的进程间通信方式,允许一个或多个进程向队列中发送消息,另一个或多个进程从中接收这些消息。以下是具体实现:
1. **创建和发送消息的程序 (sender.cpp)**
使用 `msgget` 获取消息队列 ID 并调用 ` msgsnd` 发送消息。
```cpp
#include <iostream>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msg_buffer {
long msg_type;
char msg_text[100];
};
int main() {
key_t key = ftok("progfile", 65); // 创建唯一键值
int msgid = msgget(key, 0666 | IPC_CREAT);
struct msg_buffer message;
std::cout << "Write Data : ";
std::cin.getline(message.msg_text, 100);
message.msg_type = 1; // 设置消息类型
msgsnd(msgid, &message, sizeof(message), 0); // 将消息放入队列
std::cout << "Data sent\n";
return 0;
}
```
2. **接收消息的程序 (receiver.cpp)**
调用 `msgrcv` 函数从指定的消息队列中获取消息。
```cpp
#include <iostream>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msg_buffer {
long msg_type;
char msg_text[100];
};
int main() {
key_t key = ftok("progfile", 65); // 创建唯一键值
int msgid = msgget(key, 0666 | IPC_CREAT);
struct msg_buffer message;
msgrcv(msgid, &message, sizeof(message), 1, 0); // 接收消息
std::cout << "Data Received: " << message.msg_text << "\n";
return 0;
}
```
上述代码展示了如何利用消息队列完成简单的进程间通信[^1]。
---
#### 方法二:套接字(Socket)
套接字不仅可用于网络编程,还可以用于同一台机器上的进程间通信。其核心在于建立客户端和服务端之间的连接并传输数据。
```cpp
// Server Code Example
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { // 创建socket
perror("socket failed");
exit(EXIT_FAILURE);
}
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);
bind(server_fd, (struct sockaddr *)&address, sizeof(address)); // 绑定地址到socket
listen(server_fd, 3); // 开始监听请求
while(true){
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0){ // 接受新连接
perror("accept");
exit(EXIT_FAILURE);
}
char buffer[1024] = {0};
read(new_socket , buffer, 1024); // 读取来自客户端的数据
std::cout << "Message from client: " << buffer << "\n";
send(new_socket , "Hello Client!", strlen("Hello Client!"), 0 ); // 向客户端发送响应
close(new_socket);
}
}
```
此示例说明了服务端如何通过套接字接受客户端连接并交换数据[^2]。
---
#### 方法三:管道(Pipe)
管道分为匿名管道和命名管道两种形式。匿名管道通常仅限于父子进程之间使用;而命名管道可以通过文件系统路径名访问,适合任意两个进程间的通信。
##### 匿名管道实例:
```cpp
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
int main(){
int fd[2]; // 文件描述符数组
pipe(fd); // 创建管道
pid_t pID = fork(); // 子进程分叉
if(pID > 0){
close(fd[0]); // 关闭父进程中不需要的读端
const char* text = "Hello Child!";
write(fd[1],text,strlen(text)+1); // 写入数据至管道
close(fd[1]);
}else{
close(fd[1]); // 关闭子进程中不需要的写端
char buffer[100];
read(fd[0],buffer,sizeof(buffer)); // 从管道读取数据
std::cout<< "Received Message:" << buffer <<"\n";
close(fd[0]);
}
return 0;
}
```
注意,在某些情况下,如果未正确关闭不必要的管道端口,则可能导致死锁现象发生[^3]。
---
#### 方法四:共享内存(Shared Memory)
共享内存提供了一种高效的IPC手段,允许多个进程直接操作相同的物理内存区域。为了防止竞争条件问题,常需结合信号量机制一起工作。
```cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <semaphore.h>
#define SHM_SIZE 1024
int main(int argc,char *argv[]) {
sem_t *mutex;
void *shared_memory;
int shm_fd;
shm_fd = shm_open("/my_shm", O_RDWR|O_CREAT,S_IRUSR|S_IWUSR); // 打开/创建共享内存对象
ftruncate(shm_fd,SHM_SIZE); // 设定大小
shared_memory=mmap(NULL,SHM_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,shm_fd,0);// 映射到虚拟空间
mutex=sem_open("/my_sem",O_CREAT,S_IRWXU,1); // 初始化互斥锁
strcpy((char *)shared_memory,"This is a test string."); // 写入字符串
sem_wait(mutex); // 加锁
printf("%s\n",(char*)shared_memory); // 输出内容
sem_post(mutex); // 解锁
munmap(shared_memory,SHM_SIZE); // 取消映射
shm_unlink("/my_shm"); // 删除共享内存对象
sem_close(mutex); // 销毁信号灯资源
sem_unlink("/my_sem");
return EXIT_SUCCESS;
}
```
这里展示了一个基本框架,其中包含了打开、分配以及释放共享内存的过程[^4]。
---
#### 方法五:信号(Signal)
尽管不是最常用的方式之一,但仍然可以借助标准库函数处理异步事件通知功能作为另一种选择方案。
```cpp
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
void handler(int sig_no){
puts("Caught signal!");
}
int main(void){
signal(SIGINT,&handler); /* 注册SIGINT处理器 */
while(1){
sleep(1);
}
return 0;
}
```
当捕获特定类型的中断号时触发自定义逻辑执行流程[^5]。
---
阅读全文
相关推荐

















