Linux 进程间通信
Linux进程间通信
进程间通信(IPC,Inter-Process Communication)在 Linux 下常用的方法包括:
1)管道(Pipe)
2)有名管道(FIFO)
3)消息队列(Message Queue)
4)共享内存(Shared Memory)
5)信号量(Semaphore)
6)套接字(Socket)
1. 管道(Pipe)
管道是一种最基本的 IPC 方法,适用于有亲缘关系的进程之间通信。
管道(Pipe)参考代码
#include <iostream>
#include <unistd.h>
#include <cstring>
int main() {
int ret = 0;
int pipefd[2];
pid_t pid;
char buffer[1024];
//创建管道
ret = pipe(pipefd);
std::cout <<"ret = " << ret << std::endl;
if (ret == -1) { //当ret为-1时,说明pipe函数发生错误执行失败
perror("pipe");
return 1;
}
pid = fork(); //创建子进程
std::cout << "pid= " << pid << std::endl;
if (pid < 0) {
perror("fork");
return 1;
}
if (pid == 0) { // 子进程
close(pipefd[0]); // 关闭读端
const char* message = "Hello from child process!";
write(pipefd[1], message, strlen(message) + 1);
close(pipefd[1]); // 关闭写端
} else { // 父进程
close(pipefd[1]); // 关闭写端
read(pipefd[0], buffer, sizeof(buffer));
std::cout << "Parent received: " << buffer << std::endl;
close(pipefd[0]); // 关闭读端
}
return 0;
}
管道(Pipe)输出结果
ret = 0
pid= 26087
pid= 0
Parent received: Hello from child process!
2. 有名管道(FIFO)
适用于不相关的进程。
有名管道(FIFO)参考代码
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#define FIFO_PATH "/tmp/myfifo"
int main() {
pid_t pid;
char buffer[1024];
// 创建有名管道
if (mkfifo(FIFO_PATH, 0666) == -1) {
perror("mkfifo");
}
pid = fork(); // 创建子进程
if (pid < 0) {
perror("fork");
return 1;
}
if (pid == 0) { // 子进程
int fd = open(FIFO_PATH, O_WRONLY);
const char* message = "Hello from child process!";
write(fd, message, strlen(message) + 1);
close(fd);
} else { // 父进程
int fd = open(FIFO_PATH, O_RDONLY);
read(fd, buffer, sizeof(buffer));
std::cout << "Parent received: " << buffer << std::endl;
close(fd);
unlink(FIFO_PATH); // 删除 FIFO
}
return 0;
}
有名管道(FIFO)输出结果
Parent received: Hello from child process!
3. 消息队列(Message Queue)
消息队列适合于复杂的通信需求。
消息队列(Message Queue)参考代码
#include <iostream>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
struct Message {
long msg_type;
char msg_text[100];
};
int main() {
pid_t pid;
key_t key = ftok("progfile", 65);
int msgid = msgget(key, 0666 | IPC_CREAT);
Message message;
pid = fork(); // 创建子进程
if (pid == 0) { // 子进程
message.msg_type = 1;
strcpy(message.msg_text, "Hello from child process!");
msgsnd(msgid, &message, sizeof(message.msg_text), 0);
} else { // 父进程
msgrcv(msgid, &message, sizeof(message.msg_text), 1, 0);
std::cout << "Parent received: " << message.msg_text << std::endl;
msgctl(msgid, IPC_RMID, NULL); // 删除消息队列
}
return 0;
}
消息队列(Message Queue)输出结果
Parent received: Hello from child process!
4. 共享内存(Shared Memory)
共享内存是最快的 IPC 方法,但需要同步机制。
有名管道(FIFO)参考代码
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cstring>
#include <unistd.h>
int main() {
key_t key = ftok("shmfile", 65);
int shmid = shmget(key, 1024, 0666 | IPC_CREAT);
char* str = (char*)shmat(shmid, (void*)0, 0);
pid_t pid;
pid = fork(); // 创建子进程
if (pid == 0) { // 子进程
strcpy(str, "Hello from child process!");
shmdt(str);
} else { // 父进程
sleep(1); // 确保子进程写入完成
std::cout << "Parent received: " << str << std::endl;
shmdt(str);
shmctl(shmid, IPC_RMID, NULL); // 删除共享内存
}
return 0;
}
有名管道(FIFO)输出结果
Parent received: Hello from child process!
5. 信号量(Semaphore)
信号量主要用于同步。
信号量(Semaphore)参考代码
#include <iostream>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
void semaphore_op(int semid, int op) {
struct sembuf sop = {0, static_cast<short> (op), 0};
semop(semid, &sop, 1);
}
int main() {
key_t key = ftok("semfile", 65);
int semid = semget(key, 1, 0666 | IPC_CREAT);
semctl(semid, 0, SETVAL, 0);
pid_t pid;
pid = fork(); //创建子进程
if (pid == 0) { // 子进程
std::cout << "Child: Writing data...\n";
sleep(2);
semaphore_op(semid, 1); // 信号量加 1
std::cout << "Child: Data written.\n";
} else { // 父进程
std::cout << "Parent: Waiting for data...\n";
semaphore_op(semid, -1); // 等待信号量变为 0
std::cout << "Parent: Data received.\n";
semctl(semid, 0, IPC_RMID); // 删除信号量
}
return 0;
}
`
信号量(Semaphore)输出结果
Parent: Waiting for data...
Child: Writing data...
Child: Data written.
Parent: Data received.
6. 套接字(Socket)
适用于网络通信或本地进程间通信。
套接字(Socket)参考代码
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstring>
int main() {
int sv[2]; // Socket pair
char buffer[1024];
pid_t pid;
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
perror("socketpair");
return 1;
}
pid = fork(); // 创建子进程
if (pid == 0) { // 子进程
close(sv[0]);
const char* message = "Hello from child process!";
write(sv[1], message, strlen(message) + 1);
close(sv[1]);
} else { // 父进程
close(sv[1]);
read(sv[0], buffer, sizeof(buffer));
std::cout << "Parent received: " << buffer << std::endl;
close(sv[0]);
}
return 0;
}
套接字(Socket)输出结果
Parent received: Hello from child process!
原文地址:https://blog.csdn.net/chenmi123321/article/details/144314194
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!