电子说
进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享内存、Socket(套接字)等。其中 Socket和支持不同主机上的两个进程IPC。
管道,通常指无名管道,是 UNIX 系统IPC最古老的形式。
intpipe(int fd[2]); // 返回值:若成功返回0,失败返回-1;
当一个管道建立时,它会创建两个文件描述符:fd[0]为读而打开,fd[1]为写而打开。如下图:
要关闭管道只需将这两个文件描述符关闭即可。
单个进程中的管道几乎没有任何用处。所以,通常调用 pipe 的进程接着调用 fork,这样就创建了父进程与子进程之间的 IPC 通道。如下图所示:
若要数据流从父进程流向子进程,则关闭父进程的读端(fd[0])与子进程的写端(fd[1]);反之,则可以使数据流从子进程流向父进程。
int main()
{
int fd[2]; // 两个文件描述符
pid_t pid;
char buff[20];
if (pipe(fd) < 0)
{
printf("Create Pipe Error!\\n");
}
if ((pid = fork()) < 0) // 创建子进程
{
printf("Fork Error!\\n");
}
else if (pid > 0) // 父进程
{
close(fd[0]); // 关闭读端
write(fd[1], "Hello World\\n", 12);
}
else
{
close(fd[1]); // 关闭写端
read(fd[0], buff, 20);
printf ("%s", buff);
}
return 0;
}
FIFO,也称为命名管道,是一种文件类型。
// 返回值:成功返回0, 出错返回-1
intmkfifo(constchar* pathname, mode_t mode);
其中的 mode 参数与open函数中的 mode 相同。一旦创建了一个 FIFO,就可以用一般的文件I/O函数操作它。
当 open 一个FIFO时,是否设置非阻塞标志(O_NONBLOCK)的区别:
FIFO的通信方式类似于在进程中使用文件来传输数据,只不过FIFO类型文件同时具有管道的特性。在数据读出时,FIFO管道中同时清除数据,并且“先进先出”。下面的例子演示了使用 FIFO 进行 IPC 的过程:
write_fifo.c
int main()
{
int fd;
int n, i;
char buf[1024];
time_t tp;
printf("I am %d process.\\n", getpid()); // 说明进程ID
if((fd = open("fifo1", O_WRONLY)) < 0) // 以写打开一个FIFO
{
perror("Open FIFO Failed");
exit(1);
}
for(i=0; i<10; ++i)
{
time(&tp); // 取系统当前时间
n=sprintf(buf,"Process %d's time is %s",getpid(),ctime(&tp));
printf("Send message: %s", buf); // 打印
if(write(fd, buf, n+1) < 0) // 写入到FIFO中
{
perror("Write FIFO Failed");
close(fd);
exit(1);
}
sleep(1); // 休眠1秒
}
close(fd); // 关闭FIFO文件
return 0;
}
read_fifo.c
int main()
{
int fd;
int len;
char buf[1024];
if (mkfifo("fifo 1", 0666) < 0 && errno != EXIST) // 创建FIFO管道
{
perror ("Create FIFO Failed\\n");
}
if ((fd = open("fifo 1", R_ONLY)) < 0) // 以读方式打开
{
perror ("Open FIFO Failed\\n");
exit(1);
}
while ((len == read(buf, buf, 1024)) > 0) // 读取FIFO管道
{
printf ("Read Message: %s", buf);
}
close(fd);
return 0;
}
全部0条评论
快来发表一下你的评论吧 !