Linux进程通信(IPC)机制允许进程之间交换数据和信息。以下是三种常见的Linux IPC机制:
定义: 管道是一种半双工的通信方式,数据只能单向流动,通常用于具有亲缘关系的进程之间(例如父子进程)。
类型:
特点:
示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int pipefd[2];
pid_t pid;
char buffer[256];
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));
printf("Child received: %s\n", buffer);
close(pipefd[0]);
} else { // 父进程
close(pipefd[0]); // 关闭读端
write(pipefd[1], "Hello from parent", 20);
close(pipefd[1]);
}
return 0;
}
定义: 消息队列是一种进程间通信机制,允许进程发送和接收消息。消息队列中的消息有类型,可以根据类型进行选择性接收。
特点:
示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msg_buffer {
long msg_type;
char msg_text[100];
};
int main() {
int msgid;
key_t key = 1234;
struct msg_buffer message;
// 创建消息队列
msgid = msgget(key, IPC_CREAT | 0666);
if (msgid == -1) {
perror("msgget");
exit(EXIT_FAILURE);
}
// 发送消息
message.msg_type = 1;
strcpy(message.msg_text, "Hello from sender");
if (msgsnd(msgid, &message, sizeof(message.msg_text), 0) == -1) {
perror("msgsnd");
exit(EXIT_FAILURE);
}
// 接收消息
if (msgrcv(msgid, &message, sizeof(message.msg_text), 1, 0) == -1) {
perror("msgrcv");
exit(EXIT_FAILURE);
}
printf("Received message: %s\n", message.msg_text);
// 删除消息队列
if (msgctl(msgid, IPC_RMID, NULL) == -1) {
perror("msgctl");
exit(EXIT_FAILURE);
}
return 0;
}
定义: 共享内存是最快的IPC机制之一,它允许多个进程访问同一块物理内存。进程可以将这块内存映射到自己的地址空间,从而实现数据共享。
特点:
示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
int main() {
int shmid;
key_t key = 1234;
char *shmaddr;
pid_t pid;
// 创建共享内存段
shmid = shmget(key, 1024, IPC_CREAT | 0666);
if (shmid == -1) {
perror("shmget");
exit(EXIT_FAILURE);
}
// 将共享内存段附加到进程地址空间
shmaddr = shmat(shmid, NULL, 0);
if (shmaddr == (char *) -1) {
perror("shmat");
exit(EXIT_FAILURE);
}
// 写入数据
strcpy(shmaddr, "Hello from shared memory");
pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0) { // 子进程
sleep(2); // 等待父进程写入数据
printf("Child read: %s\n", shmaddr);
shmdt(shmaddr); // 分离共享内存段
} else { // 父进程
sleep(1); // 等待子进程读取数据
printf("Parent read: %s\n", shmaddr);
shmdt(shmaddr); // 分离共享内存段
}
// 删除共享内存段
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
perror("shmctl");
exit(EXIT_FAILURE);
}
return 0;
}
选择合适的IPC机制取决于具体的应用需求和性能考虑。