it编程 > 编程语言 > C/C++

C++ 进程间通信IPC的实现示例

8人参与 2025-06-13 C/C++

进程间通信(inter-process communication, ipc)是操作系统提供的允许不同进程间交换数据和同步行为的机制。c++作为系统级编程语言,支持多种ipc方式。本文将详细介绍c++中常用的进程间通信技术。

1. 管道(pipe)

1.1 匿名管道

匿名管道是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;
}

1.2 命名管道(fifo)

命名管道克服了匿名管道的限制:

#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);

2. 消息队列(message queue)

消息队列提供了一种结构化数据交换方式:

#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;
}

3. 共享内存(shared memory)

共享内存是最快的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;
}

4. 信号量(semaphore)

信号量用于进程间同步:

#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;
}

5. 套接字(socket)

套接字是最通用的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;
}

6. 信号(signal)

信号是异步通知机制:

#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;
}

7. 文件锁(file locking)

文件锁用于协调对文件的访问:

#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;
}

8. windows特有的ipc机制

8.1 邮槽(mailslot)

// 服务器端
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);

8.2 内存映射文件(memory-mapped file)

类似于共享内存,但有文件支持

// 创建者
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, ...);

9. 高级ipc技术

9.1 d-bus

#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);

9.2 corba

// idl定义
interface hello {
    string sayhello();
};

// c++实现
class helloimpl : public virtual poa_hello {
public:
    char* sayhello() {
        return corba::string_dup("hello corba!");
    }
};

10. ipc方式比较与选择指南

ipc方式适用场景优点缺点
管道父子进程间简单通信简单易用单向通信,只能亲缘进程
命名管道任意进程间简单通信可用于无亲缘进程仍然是单向通信
消息队列结构化消息传递消息有类型,可非阻塞读取系统范围限制(队列数量、大小)
共享内存高性能大数据量通信最快ipc方式需要额外同步机制
信号量进程同步有效解决竞争条件不直接传输数据
套接字网络或本地进程通信最通用,支持不同主机开销较大
信号异步事件通知简单通知机制信息量有限
文件锁文件访问协调简单文件同步粒度较粗
d-bus桌面环境进程通信高级抽象,支持远程调用复杂度高
corba分布式系统,跨语言通信语言中立,支持复杂对象重量级,学习曲线陡峭

选择建议

11. 安全考虑

12. 性能优化技巧

13. 跨平台考虑

14. 实际应用案例

14.1 多进程日志系统

14.2 分布式计算

14.3 微服务架构

15. 总结

c++提供了丰富的进程间通信机制,从简单的管道到复杂的分布式对象系统。选择适当的ipc技术需要考虑以下因素:

理解各种ipc技术的优缺点和适用场景,可以帮助开发者构建高效、可靠的进程间通信系统。在实际项目中,往往需要组合使用多种ipc技术来满足不同的通信需求。# c++ 进程间通信(ipc)方式全面解析

到此这篇关于c++ 进程间通信ipc的实现示例的文章就介绍到这了,更多相关c++ 进程间通信ipc内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

C++中智能指针weak_ptr的原理及使用

06-13

C++ 函数 strftime 和时间格式示例详解

06-13

C++中string流的具体使用

06-11

C++作用域和标识符查找规则详解

06-10

c/c++中opencv双边滤波的实现

06-10

C语言 fgetc的用法详解以注意事项场景分析

06-10

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论