一、管道(Pipe):
管道是Linux中最简单的进程间通信机制,主要用于在具有亲缘关系的进程间传递数据。它是单向的,可以分为无名管道和有名管道。
代码示例:
#include <stdio.h>
#include <unistd.h>
int main() {
int fd[2];
char buf[256];
pipe(fd);
if (fork() == 0) {
// 子进程
close(fd[0]); // 关闭读端
write(fd[1], "Hello from child!", 17);
} else {
// 父进程
close(fd[1]); // 关闭写端
read(fd[0], buf, sizeof(buf));
printf("Parent received: %s\n", buf);
}
return 0;
}
二、消息队列(Message Queue):
消息队列是一种进程间通信方式,用于在无关联进程之间传递消息。消息队列是有名字的,允许进程通过消息队列进行异步通信。
代码示例:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf {
long mtype;
char mtext[256];
};
int main() {
int msqid;
struct msgbuf message;
key_t key = ftok(".", 'm');
msqid = msgget(key, IPC_CREAT | 0666);
if (fork() == 0) {
// 子进程
message.mtype = 1;
sprintf(message.mtext, "Hello from child!");
msgsnd(msqid, &message, sizeof(message.mtext), 0);
} else {
// 父进程
msgrcv(msqid, &message, sizeof(message.mtext), 1, 0);
printf("Parent received: %s\n", message.mtext);
}
return 0;
}
三、共享内存(Shared Memory):
共享内存是一种高效的IPC方式,允许多个进程共享同一段物理内存。但需要注意同步访问共享内存的问题。
代码示例:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main() {
int shmid;
char *shmaddr;
key_t key = ftok(".", 's');
shmid = shmget(key, 256, IPC_CREAT | 0666);
shmaddr = (char *)shmat(shmid, NULL, 0);
if (fork() == 0) {
// 子进程
sprintf(shmaddr, "Hello from child!");
} else {
// 父进程
wait(NULL); // 等待子进程写入数据
printf("Parent received: %s\n", shmaddr);
}
return 0;
}
四、套接字(Socket):
套接字是一种通用的IPC方式,可以用于本地进程间通信,也可以用于不同主机之间的网络通信。
代码示例:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
int sockfd, newsockfd, portno;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
socklen_t clilen;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
portno = 12345;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
listen(sockfd, 5);
if (fork() == 0) {
// 子进程
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
write(newsockfd, "Hello from child!", 17);
} else {
// 父进程
wait(NULL); // 等待子进程写入数据
read(sockfd, buffer, sizeof(buffer));
printf("Parent received: %s\n", buffer);
}
return 0;
}
结论:
Linux提供了多种进程间通信方式,每种方式都适用于不同的场景。管道适合父子进程之间简单数据传递,消息队列适用于无关联进程的异步通信,共享内存是高效的大数据交换方式,套接字提供通用的跨网络或本地进程间通信能力。
在实际应用中,开发者需要根据具体场景选择合适的IPC方式,并注意处理好进程间的同步与数据安全问题。正确选择IPC机制可以提高系统性能和开发效率,使进程间的通信更加稳定可靠。