【进程间通信】(一)管道

引言

  进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。另外,系统空间是“公共场所”,各进程均可以访问,所以内核也可以提供这样的条件
  进程间通信(IPC,Interprocess communication)是一组编程接口,让程序员能够协调不同的进程,使之能在一个操作系统里同时运行,并相互传递、交换信息。这使得一个程序能够在同一时间里处理许多用户的要求。因为即使只有一个用户发出要求,也可能导致一个操作系统中多个进程的运行,进程之间必须互相通话。IPC接口就提供了这种可能性。每个IPC方法均有它自己的优点和局限性,一般,对于单个程序而言使用所有的IPC方法是不常见的。
  IPC方法包括管道(PIPE)、消息队列、共享内存、信号量(旗语)、以及套接字(Socket)。

1、无名管道pipe

1.1 简述

  管道有无名管道和命名管道,以管道的进程间通信的构建较为简单,但不适合进程间频繁的数据交互。

1.2 特点

(1)无名管道pipe为半双工通信方式,具有固定的读端fd[0],写端fd[1]。即数据在同一时刻只能在一个方向传输。
(2)无名管道只能用于具有亲缘关系的进程之间通信(例如父子进程)
(3)管道是一种特殊的文件类型,只存在内存中,而不存在于文件系统。
              
在这里插入图片描述

1.3 函数原型

#include <unistd.h>
int pipe(fd[2]);//返回值:成功返回0,失败返回-1

1.4 例程

#include <sys/types.h>
#include <sys/wait.h>
int main()
{
        pid_t pid;
        int fd[2];  //无名管道参数,fd[0]为管道固定的读端,fd[1]为管道固定的写端
        char buff[128];
        if(pipe(fd) == -1) //创建无名管道
        {
                perror("create pipe failed.\n");
                exit(0);
        }else{
                if((pid = fork()) == -1) //创建子进程
                {
                        perror("fork failed.why:");
                        exit(0);
                }
                else if(pid > 0)
                {
                        printf("Ready to send message......\n");
                        sleep(3);
                        close(fd[0]); //关闭读端fd[0],向写端fd[1]写入数据
                        write(fd[1], "hello my son.\n", strlen("hello my son.\n"));
                        wait(NULL);
                }
                else if(pid == 0)
                {
                        close(fd[1]); //关闭写端fd[1],从读端fd[0]读取数据
                        read(fd[0], buff, 128);
                        printf("read from farther:%s\n", buff);
                        exit(0);
                }
        }
        return 0;
}

1.5 例程说明

父进程休眠3秒后,打开写端,关闭读端。向创建的无名管道写入数据。
子进程等待父进程写入管道中的数据。

Ready to send message......
read from farther:hello my son.

2、命名管道FIFO

2.1 简述

  命名管道可以令无关进程之间进行通信,故可以利用命名管道可以形成多个客户端(多个写端)——>一个服务器(一个读端)的多个进程间的通信。

2.2 特点

(1)FIFO可以在无关的进程之间交换数据,与无名管道不同。
(2)FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。

2.3 函数原型

#include <sys/stat.h>
// 返回值:成功返回0,出错返回-1
int mkfifo(const char *pathname, mode_t mode);

2.4 例程

read_fifo.c

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
        int ret;
        char *read_message = NULL;
        if((ret = mkfifo("FIFO", 0600)) == -1) //创建命名管道
        {
                perror("create fifo fialed.why:");
                if(errno == EEXIST)
                {
                        printf("fifo exists\n");
                }
        }else{
                printf("create fifo successfully.\n");
        }
        int fd = open("./FIFO", O_RDWR); //打开管道
        if(fd == -1)
        {
			perror("open failed.why:");
			exit(0);
		}
        read_message = (char*)malloc(sizeof(char) *128);
        read(fd, read_message, 128);//等待读取管道中的数据
        printf("Receive:%s\n", read_message);
        close(fd);
        exit(0);
}

write_fifo.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main()
{
        int fd;
        char *write_message = NULL;
        if((fd = open("./FIFO", O_RDWR)) == -1)
        {
                perror("open failed.why:");
                exit(0);
        }
        printf("open success.\n");
        write_message =(char *)malloc(sizeof(char) *128);
        gets(write_message);
        write(fd, write_message, 128);
        printf("Mr.anrang:%s\n", write_message);
        close(fd);
        exit(0);
}       

2.5 例程说明

  首先执行read_fifo.c中的程序,创建管道->打开管道->等待读取管道数据->读取管道数据->关闭管道->退出程序
  再执行write_fifo.c中的程序,打开管道->gets键入内容->向管道写入数据->关闭管道->退出程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值