美文网首页
Unix进程通信:管道

Unix进程通信:管道

作者: FakeCSer爱去网吧 | 来源:发表于2020-02-21 15:55 被阅读0次

    匿名管道

    原理
    • 内核空间的队列式内存(缓冲区)
    • 队列式内存,内核管理同步和互斥,而共享内存和文件通信需要信号量或者锁机制来保证同步互斥
    特点
    • 半双工
    • 进程全部退出后,匿名管道自动释放,所以数据无法保存
    • 可以使用read write close,不能用lseek(队列读写)
    • 常用与父子进程间通信(匿名管道来进行非亲缘进程间通信需要辅助以文件描述符?)
    • 由内核管理的队列读写方式,自带同步互斥功能

    API

    #include <unistd.h>
    int pipe(int pipefd[2]);
    

    参数表:
    pipefd[2]:读端和写端的文件描述符
    返回值:
    0:成功
    -1:出错

    示例

    /*
    匿名管道用于fork的父子进程之间
    整形数组两个成员分别是读端和写端,对应两个文件描述符
    虽然进程可以同时获得读端和写端两个文件描述符,但是,
    由于匿名管道应该是半双工的,所以真正使用的时候,
    发送方应该先关闭读端描述符,接收方应该关闭写端描述符
    如果想全双工通信,应该建立两个匿名管道,如果用一个会发生错乱
    
    pfd[0]对应读,pfd[1]对应写
    1. int pfd[2]
    2. pipe(pfd)
    3. 父write(pfd[1],"123456",7)
       子read(pdf[0],buf,7)  
    */
    
    //匿名管道用于父子进程间的通信。
    //父写子读
    #include <iostream>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    using namespace std;
    
    int main()
    {
    
        char buf[100];
        
        int pfd[2];
        
        if( ( pipe(pfd) ) == -1)
        {
            perror("pipe");
            exit(1);
        }
        
        
        int pid;
        if( ( pid=fork() ) == -1)
        {
            perror("fork");
            exit(1);    
        }
        else if(pid == 0)//子进程,读
        {
            close(pfd[1]);
            sleep(1);
            read(pfd[0],buf,7);
            cout << buf << endl;
            close(pfd[0]);
        }
        else
        {
            close(pfd[0]);
            write(pfd[1],"123456",7);//父进程,写
            close(pfd[1]);
            wait(NULL);
            
        }
    
        return 0;
    }
    
    

    命名管道

    原理
    • 内核空间的队列式内存
    • 又名(FIFO文件)
    特点
    • 文件系统可见,有对应的文件节点信息
    • 虽然文件系统里有,但是硬盘中没有
    • 因为有名称,非亲缘进程可以依靠他通信
    • 按照文件操作进行操作(lseek除外)
    API
    #include <sys/stat.h>
    int mkfifo(char *filename,mode_t mode);
    

    参数表:
    filename:命名管道名称
    mode:使用方式(如0644)
    返回值:
    0:成功
    -1:失败

    示例代码

    写端

      1 #include <sys/stat.h>//mkfifo() 
      2 #include <sys/types.h>
      3 #include <fcntl.h>
      4 #include <unistd.h>//sleep(),write(),close()
      5 
      6 int main()
      7 {
      8         char buf[100];
      9         int fd;
     10 
     11 
     12 
     13         mkfifo("testpipe",0644);
     14         fd = open("testpipe",O_WRONLY);
     15         write(fd,"123456",7);
     16         close(fd);
     17 
     18         sleep(10);
     19         return 0;
     20 }    
    

    读端

      1 #include <sys/stat.h>
      2 #include <sys/types.h>
      3 #include <fcntl.h>
      4 #include <unistd.h>
      5 
      6 #include <iostream>
      7 using namespace std;
      8 
      9 int main()
     10 {
     11         char buf[100];
     12         int fd;
     13         sleep(1);
     14         fd = open("testpipe",O_RDONLY);
     15         read(fd,buf,7);
     16         cout << buf <<endl;
     17         
     18         close(fd);
     19         return 0;
     20 }                                                                                           
    

    相关文章

      网友评论

          本文标题:Unix进程通信:管道

          本文链接:https://www.haomeiwen.com/subject/hvycqhtx.html