Linux系统提供了多种方式实现多进程之间的通信,以下是三种常用的方法供初学者参考。
管道(Pipe):管道是一种半双工的通信方式,只能在具有亲缘关系的进程之间使用。一个进程向管道写入数据,而另一个进程则从管道读取数据。Linux中的管道可以使用pipe()函数创建,它返回两个文件描述符,一个用于读取数据,另一个用于写入数据。下面是一个简单的例子
#include
#include
int main(void) {
int fd[2];
char buf[20];
pipe(fd);
if (fork() == 0) {
close(fd[0]);
write(fd[1], "hello world", 12);
} else {
close(fd[1]);
read(fd[0], buf, 12);
printf("%s\n", buf);
}
return 0;
}
这段代码创建了一个管道,然后创建了一个子进程。子进程关闭管道的读端,然后向管道中写入数据;父进程关闭管道的写端,然后从管道中读取数据并输出。
共享内存(Shared Memory):共享内存是一种高效的进程间通信方式,多个进程可以访问同一块物理内存,从而避免了复制数据的开销。Linux中的共享内存可以使用shmget()、shmat()和shmdt()函数创建和管理,其中shmget()函数创建共享内存段,shmat()函数将共享内存映射到进程的地址空间中,shmdt()函数则解除共享内存的映射。下面是一个简单的例子:
#include
#include
#include
#include
int main(void) {
int shmid;
char *shmaddr;
shmid = shmget(IPC_PRIVATE, 1024, IPC_CREAT | 0666);
if (fork() == 0) {
shmaddr = shmat(shmid, NULL, 0);
sprintf(shmaddr, "hello world");
exit(0);
} else {
wait(NULL);
shmaddr = shmat(shmid, NULL, 0);
printf("%s\n", shmaddr);
shmdt(shmaddr);
shmctl(shmid, IPC_RMID, NULL);
}
return 0;
}
这段代码创建了一个共享内存段,然后创建了一个子进程。子进程将共享内存映射到自己的地址空间中,然后向共享内存中写入数据;父进程等待子进程结束,然后再将共享内存映射到自己的地址空间中,从共享内存中读取数据并输出。
消息队列(Message Queue):消息队列是一种基于消息的通信方式,可以在不同进程之间传递数据。Linux中的消息队列可以使用msgget()、msgsnd()和msgrcv()函数创建和管理,其中msgget()函数创建消息队列,msgsnd()函数向消息队列发送消息,msgrcv()函数从消息队列中接收消息。下面是一个简单的例子:
#include
#include
#include
#include
struct msgbuf {
long mtype;
char mtext[20];
};
int main(void) {
int msqid;
struct msgbuf msg;
msqid = msgget(IPC_PRIVATE, IPC_CREAT | 0666);
if (fork() == 0) {
msg.mtype = 1;
sprintf(msg.mtext, "hello world");
msgsnd(msqid, &msg, sizeof(msg.mtext), 0);
exit(0);
} else {
wait(NULL);
msgrcv(msqid, &msg, sizeof(msg.mtext), 1, 0);
printf("%s\n", msg.mtext);
msgctl(msqid, IPC_RMID, NULL);
}
return 0;
}
这段代码创建了一个消息队列,然后创建了一个子进程。子进程向消息队列中发送消息,指定消息类型为1;父进程等待子进程结束,然后从消息队列中接收消息,并输出消息内容。最后,程序调用msgctl()函数删除消息队列。
除了上述三种方法外,Linux还提供了其他一些进程间通信方式,例如信号(Signal)、套接字(Socket)等。这些方法各有优缺点,大家可以根据具体需求选择适合的方式。