我们学习高级进程通信,指用户可直接利用操作系统所提供的一组通信命令高效地传送大量数据的一种通信方式。
进程间通信的几种主要手段:管道、消息队列、共享内存、套接字
管道
管道,指用于连接一个读进程和一个写进程以实现它们之间通信的一个共享文件,只存在于内存中,是一种两个进程间进行单向通信的机制。在创建管道时,系统为管道分配一个页面作为数据缓冲区,通过管道通信的两个进程通过读写这个缓冲区来进程通信,写在缓冲区尾部,从头部读取数据。
局限性:
数据单向传递,即半双工;管道没有名字,只能用于具有亲缘关系的进程间通信;管道的缓冲区大小受限制;管道传送的是无格式的字节流。
管道的创建:
int pipe(int fd[2]) //调用成功返回0,且数组中包含两个新的fd,失败返回-1
管道两端分别用fd[0]和fd[1]描述,管道两端的任务固定,fd[0]只能用于读,称为管道读端;fd[1]只能用于写,称为管道写端。
管道一旦创建成功,就可以作为一般的文件来使用,对一般文件进行操作的I/O函数也适用于管道。
管道的读写:如果某进程要读取管道中的数据,那么该进程应当关闭fd[1],同时向管道写数据的进程应当关闭fd[0]。向管道中写数据类似。
这两个例子中pipe在fork之前调用,让子进程可以直接共享父进程的文件描述符。但是如果子进程调用exec函数执行另外一个程序时,就不能共享了。这种情况下可以将子进程中的文件描述符重定向到标准输入,当新执行的程序从标准输入获取数据时实际上是从父进程中获取输入数据。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
/*read pipe*/
void read_from_pipe(int fd)
{
char message[100];
read(fd,message,100);
printf("read from pipe:%s\n",message);
}
/*write pipe*/
void write_from_pipe(int fd)
{
char message[100];
printf("input message: ");
scanf("%s",message);
write(fd,message,strlen(message)+1);
}
int main()
{
int fd[2];
pid_t pid;
int stat_val;