在Linux上,C++可以通过多种方式实现进程间通信(IPC)。以下是一些常用的IPC方法:
管道是一种半双工的通信方式,通常用于父子进程之间的通信。
#include <iostream>
#include <unistd.h>
int main() {
int pipefd[2];
pid_t pid;
char buffer[10];
// 创建管道
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
// 创建子进程
pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0) { // 子进程
close(pipefd[1]); // 关闭写端
read(pipefd[0], buffer, sizeof(buffer));
std::cout << "Child received: " << buffer << std::endl;
close(pipefd[0]);
} else { // 父进程
close(pipefd[0]); // 关闭读端
write(pipefd[1], "Hello from parent", 18);
close(pipefd[1]);
}
return 0;
}
命名管道允许不相关的进程之间进行通信。
#include <iostream>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
const char* fifo_name = "/tmp/myfifo";
mkfifo(fifo_name, 0666);
int fd = open(fifo_name, O_RDWR);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
const char* message = "Hello from FIFO";
write(fd, message, strlen(message) + 1);
char buffer[10];
read(fd, buffer, sizeof(buffer));
std::cout << "Received: " << buffer << std::endl;
close(fd);
unlink(fifo_name);
return 0;
}
消息队列允许进程以消息的形式进行通信。
#include <iostream>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <cstring>
struct msg_buffer {
long msg_type;
char msg_text[100];
};
int main() {
key_t key = ftok("msgqueue.c", 65);
int msgid = msgget(key, 0666 | IPC_CREAT);
if (msgid == -1) {
perror("msgget");
exit(EXIT_FAILURE);
}
msg_buffer buffer;
buffer.msg_type = 1;
strcpy(buffer.msg_text, "Hello from message queue");
if (msgsnd(msgid, &buffer, sizeof(buffer.msg_text), 0) == -1) {
perror("msgsnd");
exit(EXIT_FAILURE);
}
if (msgrcv(msgid, &buffer, sizeof(buffer.msg_text), 1, 0) == -1) {
perror("msgrcv");
exit(EXIT_FAILURE);
}
std::cout << "Received: " << buffer.msg_text << std::endl;
msgctl(msgid, IPC_RMID, NULL);
return 0;
}
共享内存允许多个进程共享同一块内存区域。
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cstring>
int main() {
key_t key = ftok("shmfile.c", 65);
int shmid = shmget(key, 1024, 0666 | IPC_CREAT);
if (shmid == -1) {
perror("shmget");
exit(EXIT_FAILURE);
}
char* str = (char*) shmat(shmid, (void*)0, 0);
if (str == (char*)(-1)) {
perror("shmat");
exit(EXIT_FAILURE);
}
strcpy(str, "Hello from shared memory");
std::cout << "Message written in memory: " << str << std::endl;
shmdt(str);
return 0;
}
信号量用于进程同步和互斥。
#include <iostream>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <unistd.h>
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
int main() {
key_t key = ftok("semaphore.c", 65);
int semid = semget(key, 1, 0666 | IPC_CREAT);
if (semid == -1) {
perror("semget");
exit(EXIT_FAILURE);
}
union semun arg;
arg.val = 1; // 初始化信号量为1
if (semctl(semid, 0, SETVAL, arg) == -1) {
perror("semctl");
exit(EXIT_FAILURE);
}
// P操作(等待信号量)
struct sembuf sb = {0, -1, SEM_UNDO};
if (semop(semid, &sb, 1) == -1) {
perror("semop");
exit(EXIT_FAILURE);
}
std::cout << "Semaphore value: " << arg.val << std::endl;
// V操作(释放信号量)
sb.sem_op = 1;
if (semop(semid, &sb, 1) == -1) {
perror("semop");
exit(EXIT_FAILURE);
}
semctl(semid, 0, IPC_RMID, arg);
return 0;
}
套接字是一种通用的IPC机制,支持本地和网络通信。
#include <iostream>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <string.h>
int main() {
struct sockaddr_un addr;
int sockfd, newsockfd;
socklen_t addr_len = sizeof(addr);
char buffer[1024];
// 创建套接字
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
// 设置地址
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, "/tmp/unix_socket", sizeof(addr.sun_path) - 1);
// 绑定套接字
if (bind(sockfd, (struct sockaddr*)&addr, addr_len) == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
// 监听连接
listen(sockfd, 5);
newsockfd = accept(sockfd, (struct sockaddr*)&addr, &addr_len);
if (newsockfd == -1) {
perror("accept");
exit(EXIT_FAILURE);
}
// 接收数据
read(newsockfd, buffer, sizeof(buffer));
std::cout << "Received: " << buffer << std::endl;
// 发送数据
const char* message = "Hello from UNIX socket";
write(newsockfd, message, strlen(message) + 1);
close(newsockfd);
close(sockfd);
return 0;
}
这些是Linux上C++常用的进程间通信方法。选择哪种方法取决于具体的应用场景和需求。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
推荐阅读:Linux C++中如何进行进程间通信