[Linux] 进程间通信
进程间通信(Inter-Process Communication, IPC)是指不同进程之间的数据交换与协作。在Linux中,进程间通信有多种方式,每种方式都有其适用的场景。本文将介绍Linux中常见的几种进程间通信方法:管道(Pipe)、命名管道(Named Pipe)、消息队列、共享内存和信号。
1. 管道(Pipe)
管道是最常见的进程间通信方式之一,允许一个进程将输出数据通过管道传递给另一个进程。管道提供的是字节流的通信方式,数据按顺序流动。
匿名管道:只能在父子进程之间使用,通过pipe()
系统调用创建。父进程写入数据,子进程从管道中读取。
int fd[2];
pipe(fd);
write(fd[1], "Hello, Pipe!", 12);
char buffer[12];
read(fd[0], buffer, 12);
命名管道:可以在任意进程之间通信,通过mkfifo()
函数创建命名管道。
mkfifo("/tmp/myfifo", 0666);
int fd = open("/tmp/myfifo", O_RDONLY);
2. 消息队列(Message Queues)
消息队列提供了一个按消息顺序存储和传递数据的机制。通过msgget()
、msgsnd()
、msgrcv()
等系统调用操作消息队列。与管道不同,消息队列是基于消息而非字节流的,支持多种进程同时访问。
int msgid = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
struct msgbuf {
long mtype;
char mtext[100];
};
msgsnd(msgid, &msg, sizeof(msg), 0);
msgrcv(msgid, &msg, sizeof(msg), 0, 0);
3. 共享内存(Shared Memory)
共享内存允许多个进程共享同一块内存区域,效率高于其他IPC机制。通过shmget()
、shmat()
、shmdt()
和shmctl()
等系统调用进行操作。共享内存需要借助信号量或互斥锁来实现进程间的同步和互斥。
int shmid = shmget(IPC_PRIVATE, 1024, IPC_CREAT | 0666);
char *shm = shmat(shmid, NULL, 0);
strcpy(shm, "Shared memory message");
shmdt(shm);
4. 信号(Signals)
信号是Linux中用来通知进程某种事件发生的机制。信号可以由内核或其他进程发送。常见的信号有SIGINT
(中断信号)、SIGKILL
(终止信号)等。进程可以通过signal()
或sigaction()
系统调用注册信号处理函数。
signal(SIGINT, sig_handler);
5. 套接字(Sockets)
套接字是用于进程间通信的一种更强大的机制,它不仅可以在同一台机器上使用,还可以跨网络进行通信。通过socket()
、bind()
、listen()
、accept()
、send()
、recv()
等系统调用进行套接字操作。常见的通信方式有TCP/IP和UNIX域套接字。
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
listen(sockfd, 5);
总结
Linux提供了丰富的进程间通信机制,选择合适的IPC方式取决于应用的需求。管道和消息队列适用于简单的数据传递,共享内存适合大数据量的高速传输,信号适用于异步事件的通知,而套接字则适合跨网络或不同主机的通信。
了解这些IPC方式,有助于在设计进程间协作时做出更有效的决策,提高系统的性能和可靠性。