Linux进程间通信
Linux进程间通信
进程间通信概述
进程间通信(IPC)是指不同进程之间交换数据的机制。
主要IPC方式
管道(Pipe)
管道是最简单的IPC方式,用于父子进程之间通信。
#include <unistd.h>
int pipefd[2];
pipe(pipefd);
// 父进程写入
write(pipefd[1], "hello", 5);
// 子进程读取
char buf[10];
read(pipefd[0], buf, 5);
命名管道(FIFO)
命名管道可以在不相关的进程之间通信。
# 创建命名管道
mkfifo /tmp/mypipe
# 进程1写入
echo "hello" > /tmp/mypipe
# 进程2读取
cat /tmp/mypipe
消息队列
// System V消息队列
#include <sys/msg.h>
int msqid = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
struct msgbuf {
long mtype;
char mtext[100];
};
// 发送消息
struct msgbuf msg = {1, "hello"};
msgsnd(msqid, &msg, sizeof(msg.mtext), 0);
// 接收消息
msgrcv(msqid, &msg, sizeof(msg.mtext), 1, 0);
共享内存
共享内存是最快的IPC方式,多个进程可以访问同一块内存。
#include <sys/shm.h>
// 创建共享内存
int shmid = shmget(IPC_PRIVATE, 4096, 0666 | IPC_CREAT);
// 映射到进程地址空间
void *ptr = shmat(shmid, NULL, 0);
// 写入数据
strcpy(ptr, "hello");
// 从另一个进程读取
char *data = (char *)shmat(shmid, NULL, 0);
printf("%s\n", data);
// 分离共享内存
shmdt(ptr);
信号量
信号量用于进程同步,控制对共享资源的访问。
#include <sys/sem.h>
// 创建信号量集
int semid = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);
// 初始化信号量值
semctl(semid, 0, SETVAL, 1);
// P操作(等待)
struct sembuf op = {0, -1, 0};
semop(semid, &op, 1);
// V操作(释放)
struct sembuf op = {0, 1, 0};
semop(semid, &op, 1);
信号
信号是异步通信方式。
#include <signal.h>
// 注册信号处理函数
void handler(int sig) {
printf("Received signal %d\n", sig);
}
signal(SIGUSR1, handler);
// 发送信号
kill(pid, SIGUSR1);
Socket
Socket是最通用的IPC方式,支持网络通信。
#include <sys/socket.h>
// 创建socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
// 绑定地址
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
addr.sin_addr.s_addr = INADDR_ANY;
bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
// 监听
listen(sockfd, 5);
// 接受连接
int clientfd = accept(sockfd, NULL, NULL);
实践:管道通信示例
#!/bin/bash
# 使用命名管道实现进程通信
# 创建命名管道
mkfifo /tmp/pipe_example 2>/dev/null
# 启动接收进程(后台)
(
while true; do
read message < /tmp/pipe_example
echo "收到: $message"
done
) &
RECEIVER_PID=$!
# 发送消息
echo "Hello from sender" > /tmp/pipe_example
echo "Hello again" > /tmp/pipe_example
# 清理
sleep 1
kill $RECEIVER_PID
rm /tmp/pipe_example
IPC方式比较
| 方式 | 速度 | 复杂度 | 适用场景 |
|---|---|---|---|
| 管道 | 快 | 低 | 父子进程 |
| 消息队列 | 中 | 中 | 结构化消息 |
| 共享内存 | 最快 | 高 | 大量数据 |
| 信号量 | - | 中 | 同步控制 |
| Socket | 中 | 高 | 网络通信 |
总结
IPC是多进程编程的基础。根据应用场景选择合适的IPC方式,能够提高程序的性能和可维护性。