Linux---进程间通信方式

进程间通信时什么?

在Linux下每一个进程都拥有自己的虚拟的值空间, 因此进程与进程之间都是相互独立的, 所以当两个进程之间想要进行数据交互的时候, 他们自身是没有办法完成的, 所以操作系统为进程之间提供了进程间的通信方式, 也就是为进程之间提供了一个公共的媒介.

进程间通信所完成的任务

  • 进程间数据传输
  • 数据共享
  • 进程控制
  • 事件通知

进程间通信方式

  • 管道(命名管道/匿名管道)

管道在进程间通信主要实现的就是进程间数据的传输 , 并且他是一个半双工通信, 意为 : 管道中传输的数据,只能从一端单项的流向另外一端.
管道的操作是一个IO操作 , 当管道创建成功之后, 会返回句柄–该句柄为两个文件描述符, 其中一个用于读, 另一个用于写.
管道的创建是用户通过调用系统调用接口, 操作系统在内核态创建出管道供进程之间使用.

匿名管道/命名管道 : 很显然, 命名管道就是拥有名字的管道,进程在对其进行使用时, 可以直接通过名字来使用, 而匿名管道在创建之后,是没有名字的, 因此一个金层想要操作该管道, 必须满足此进程为创建匿名管道进程的子进程. 因为具有亲缘关系的进程之间的PCB是复制而来的.
总而言之: 匿名管道,只能用于具有亲缘关系的进程间通信. 命名管道可以用于任意的进程间通信

管道的原理

管道实际上是操作系统在内核中提供的一块缓冲区(只要进程能够访问到这块缓冲就可以实现通信)
通过代码的实现我们可以发现这块缓冲区的大小大致为64K;

//创建匿名管道
int pipe(int pipefd[2]);
//pipefd[2]中,我们定义pipefd[0]用来读取数据, pipe[1]用来写入数据

     int main(){
         int pipefd[2];
         int ret=pipe(pipefd);
         if(ret<0){
            perror("crtater pipe error");
            return -1;
        }
        //pipefd[0]---用来读取数据    pipefd[1]---用来写入数据;                                                                                                            
        int pid=fork();
        if(pid<0){
            perror("creater fork error");
            return -1;
        }else if(pid==0){
            //父进程--写入数据
            int i=0;
            while(1){
                char *str="Today wa stree men not goto study!";
                i+=write(pipefd[1],str,strlen(str));
                printf("%d\n",i);
                if(ret<0){
                    perror("write error");
                    return -1;
                }
            }
        }
                else{
                    //子进程---读取数据
                    char buf[1024]={0};
                    int ret=read(pipefd[0],buf,1023);
                    if(ret<0){
                        perror("read error");
                        return -1;
                    }
                    printf("buf---[%s]\n",buf);
                }
                return 0;
            }

管道的读写特性

  • 若管道中没有数据, 则read会阻塞,直到读取到数据(有数据写入管道)
  • 若管道中数据满了, 则write会阻塞, 直到有空闲空间(有数据被取走了)
  • 若所有读端被关闭, 则write会触发异常—发送SIGPIPE信号(导致进程退出)
  • 若所有写端被关闭, 则read读完数据之后不会阻塞直接返回0

因此, 进程在操作管道的时候, 如果没有用到某一段, 则要把这一端关闭掉

你可能感兴趣的:(Linux)