8人参与 • 2025-06-13 • C/C++
进程间通信(inter-process communication, ipc)是操作系统提供的允许不同进程间交换数据和同步行为的机制。c++作为系统级编程语言,支持多种ipc方式。本文将详细介绍c++中常用的进程间通信技术。
匿名管道是unix-like系统中最基础的ipc方式,具有以下特点:
#include <unistd.h> #include <iostream> int main() { int fd[2]; pipe(fd); // 创建管道 if (fork() == 0) { // 子进程 close(fd[0]); // 关闭读端 write(fd[1], "hello", 6); close(fd[1]); } else { // 父进程 close(fd[1]); // 关闭写端 char buf[20]; read(fd[0], buf, sizeof(buf)); std::cout << "received: " << buf << std::endl; close(fd[0]); } return 0; }
命名管道克服了匿名管道的限制:
#include <sys/stat.h> #include <fcntl.h> #include <unistd.h> // 进程1: 创建并写入fifo mkfifo("/tmp/myfifo", 0666); int fd = open("/tmp/myfifo", o_wronly); write(fd, "hello fifo", 10); close(fd); // 进程2: 读取fifo int fd = open("/tmp/myfifo", o_rdonly); char buf[20]; read(fd, buf, sizeof(buf)); close(fd);
消息队列提供了一种结构化数据交换方式:
#include <sys/ipc.h> #include <sys/msg.h> #include <iostream> struct message { long mtype; char mtext[100]; }; int main() { key_t key = ftok("progfile", 65); int msgid = msgget(key, 0666 | ipc_creat); message msg; msg.mtype = 1; sprintf(msg.mtext, "hello message queue"); // 发送消息 msgsnd(msgid, &msg, sizeof(msg.mtext), 0); // 接收消息 msgrcv(msgid, &msg, sizeof(msg.mtext), 1, 0); std::cout << "received: " << msg.mtext << std::endl; // 删除消息队列 msgctl(msgid, ipc_rmid, null); return 0; }
共享内存是最快的ipc方式:
#include <sys/ipc.h> #include <sys/shm.h> #include <iostream> int main() { key_t key = ftok("shmfile", 65); int shmid = shmget(key, 1024, 0666 | ipc_creat); // 附加共享内存 char *str = (char*)shmat(shmid, (void*)0, 0); std::cout << "write data: "; std::cin.getline(str, 1024); std::cout << "data in memory: " << str << std::endl; // 分离共享内存 shmdt(str); // 删除共享内存 shmctl(shmid, ipc_rmid, null); return 0; }
信号量用于进程间同步:
#include <sys/ipc.h> #include <sys/sem.h> #include <iostream> union semun { int val; struct semid_ds *buf; unsigned short *array; }; int main() { key_t key = ftok("semfile", 65); int semid = semget(key, 1, 0666 | ipc_creat); semun su; su.val = 1; // 初始值 semctl(semid, 0, setval, su); sembuf sb = {0, -1, 0}; // p操作 semop(semid, &sb, 1); // 临界区代码 std::cout << "in critical section" << std::endl; sb.sem_op = 1; // v操作 semop(semid, &sb, 1); return 0; }
套接字是最通用的ipc方式:
// 服务器端 #include <sys/socket.h> #include <netinet/in.h> #include <iostream> int main() { int server_fd = socket(af_inet, sock_stream, 0); sockaddr_in address; 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)); listen(server_fd, 3); int new_socket = accept(server_fd, null, null); char buffer[1024] = {0}; read(new_socket, buffer, 1024); std::cout << "message: " << buffer << std::endl; close(new_socket); close(server_fd); return 0; } // 客户端 #include <sys/socket.h> #include <arpa/inet.h> int main() { int sock = socket(af_inet, sock_stream, 0); sockaddr_in serv_addr; serv_addr.sin_family = af_inet; serv_addr.sin_port = htons(8080); inet_pton(af_inet, "127.0.0.1", &serv_addr.sin_addr); connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); send(sock, "hello socket", 12, 0); close(sock); return 0; }
信号是异步通知机制:
#include <signal.h> #include <unistd.h> #include <iostream> void handler(int sig) { std::cout << "received signal: " << sig << std::endl; } int main() { signal(sigint, handler); // 注册信号处理函数 std::cout << "waiting for signal..." << std::endl; pause(); // 等待信号 return 0; }
文件锁用于协调对文件的访问:
#include <sys/file.h> #include <fcntl.h> #include <unistd.h> #include <iostream> int main() { int fd = open("testfile.txt", o_rdwr | o_creat, 0666); // 获取排他锁 if (flock(fd, lock_ex) == -1) { perror("flock"); return 1; } // 临界区操作 write(fd, "hello file lock", 15); // 释放锁 flock(fd, lock_un); close(fd); return 0; }
// 服务器端 handle hmailslot = createmailslot( "\\\\.\\mailslot\\sample_mailslot", 0, mailslot_wait_forever, null); // 客户端 handle hfile = createfile( "\\\\.\\mailslot\\sample_mailslot", generic_write, file_share_read, null, open_existing, file_attribute_normal, null);
类似于共享内存,但有文件支持
// 创建者 handle hfile = createfile("shared.dat", ...); handle hmap = createfilemapping(hfile, ...); lpvoid pbuf = mapviewoffile(hmap, ...); // 访问者 handle hmap = openfilemapping(file_map_all_access, false, "sharedmemory"); lpvoid pbuf = mapviewoffile(hmap, ...);
#include <dbus/dbus.h> dbusconnection* conn = dbus_bus_get(dbus_bus_session, null); dbus_bus_request_name(conn, "com.example.service", 0, null); dbusmessage* msg = dbus_message_new_signal( "/com/example/object", "com.example.interface", "signalname"); dbus_connection_send(conn, msg, null); dbus_message_unref(msg);
// idl定义 interface hello { string sayhello(); }; // c++实现 class helloimpl : public virtual poa_hello { public: char* sayhello() { return corba::string_dup("hello corba!"); } };
ipc方式 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
管道 | 父子进程间简单通信 | 简单易用 | 单向通信,只能亲缘进程 |
命名管道 | 任意进程间简单通信 | 可用于无亲缘进程 | 仍然是单向通信 |
消息队列 | 结构化消息传递 | 消息有类型,可非阻塞读取 | 系统范围限制(队列数量、大小) |
共享内存 | 高性能大数据量通信 | 最快ipc方式 | 需要额外同步机制 |
信号量 | 进程同步 | 有效解决竞争条件 | 不直接传输数据 |
套接字 | 网络或本地进程通信 | 最通用,支持不同主机 | 开销较大 |
信号 | 异步事件通知 | 简单通知机制 | 信息量有限 |
文件锁 | 文件访问协调 | 简单文件同步 | 粒度较粗 |
d-bus | 桌面环境进程通信 | 高级抽象,支持远程调用 | 复杂度高 |
corba | 分布式系统,跨语言通信 | 语言中立,支持复杂对象 | 重量级,学习曲线陡峭 |
选择建议:
c++提供了丰富的进程间通信机制,从简单的管道到复杂的分布式对象系统。选择适当的ipc技术需要考虑以下因素:
理解各种ipc技术的优缺点和适用场景,可以帮助开发者构建高效、可靠的进程间通信系统。在实际项目中,往往需要组合使用多种ipc技术来满足不同的通信需求。# c++ 进程间通信(ipc)方式全面解析
到此这篇关于c++ 进程间通信ipc的实现示例的文章就介绍到这了,更多相关c++ 进程间通信ipc内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论