精华内容
下载资源
问答
  • 创建有名管道

    千次阅读 2013-07-11 11:52:33
    有名管道创建后,可以在任意两个进程间进行通讯 下面写了两个程序,一个往管道里写数据,一个从管道里读数据,他们的代码只有个别不一样,大部分都相同。 /**********该程序向管道里写数据********/ #include...

    有名管道创建后,可以在任意两个进程间进行通讯

    下面写了两个程序,一个往管道里写数据,一个从管道里读数据,他们的代码只有个别不一样,大部分都相同。


    /**********该程序向管道里写数据********/
    #include <stdio.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #define N 64

    int main()
    {
        int fd;
        int n;
        char buf[N];
        if (mkfifo("pipe", 0666) == -1)  //判断管道文件是否存在
        {
            if (errno != EEXIST)    //如果文件存在,则什么也不执行,如果是其他错误,则退出
            {
                perror("mkfifo");
                return -1;
            }
        }
        if ((fd = open("pipe", O_WRONLY)) == -1) //以只写方式打开管道文件,默认追加到文件后面(队列)
        {
            perror("open pipe");
            return -1;
        }
        while (fgets(buf, N, stdin) != NULL)    
        {
            n = strlen(buf);
            if (write(fd, buf, n+1) == -1) //向管道里写数据
            {
                perror("write");
                return -1;
            }
        }

        close(fd);
        return 0;
    }


    /***********该程序从管道里读数据*************/
    #include <stdio.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #define N 64

    int main()
    {
        int fd;
        ssize_t n;
        char buf[N];
        if (mkfifo("pipe", 0666) == -1)
        {
            if (errno != EEXIST)
            {
                perror("mkfifo");
                return -1;
            }
        }
        if ((fd = open("pipe", O_RDONLY)) == -1)
        {
            perror("open pipe");
            return -1;
        }
        while (1)
        {
            if ((n = read(fd, buf, N)) > 0)
            {
                printf("n = %d, buf = %s\n", n, buf);
            }
        }

        close(fd);
        return 0;
    }


    展开全文
  • 创建一个有名管道,解决无血缘关系的进程之间的通信; 创建管道的函数 #include #include int mkfifo(const char *pathname, mode_t mode); 首先创建一个有名管道myfifo 命令是: mkfifo myfifo 也可以直接...

    创建一个有名管道,解决无血缘关系的进程之间的通信;

    创建管道的函数

    #include <sys/types.h>
    #include <sys/stat.h>
    int mkfifo(const char *pathname, mode_t mode);

    首先创建一个有名管道myfifo   命令是: mkfifo myfifo

    也可以直接使用上边的函数直接在代码中实现管道。


    然后分别创建两个“.c”文件,fifo_w.c  fifo_r.c 

    fifo_w.c 
    #include <stdio.h>#include <stdlib.h>#include <unistd.h>
    #include <sys/stat.h>#include <fcntl.h>#include <string.h>
    void sys_err(char *str, int exitno)
    {
    	perror(str);
    	exit(exitno);
    }
    int main(int argc, char *argv[])
    {
    	int fd;
    	char buf[1024] = "hello xuxing\n";
    	if (argc < 2) {
    		printf("./a.out filename\n");
    		exit(1);
    	}
    	//fd = open(argv[1], O_RDONLY);
    	fd = open(argv[1], O_WRONLY);
    	if (fd < 0) {
    		sys_err("open", 1);
    	}
    	write(fd, buf, strlen(buf));
    	close(fd);
    	return 0;
    }
    

    fifo_r.c 
    #include <stdio.h>#include <stdlib.h>#include <unistd.h>
    #include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <sys/types.h>
    void sys_err(char *str, int exitno)
    {
    	perror(str);
    	exit(exitno);
    }
    int main(int argc, char *argv[])
    {
    	int fd, len;
    	char buf[1024];
    
    	if (argc < 2) {
    		printf("./a.out filename\n");
    		exit(1);
    	}
    	fd = open(argv[1], O_RDONLY);
    	//fd = open(argv[1], O_WRONLY);
    	if (fd < 0) {
    
    		sys_err("open", 1);
    	}
    	len = read(fd, buf, sizeof(buf)); //读文件
    	write(STDOUT_FILENO, buf, len);   //打印读取的内容
    	close(fd);
    
    	return 0;
    }


    运行结果:

     



    创建的有名管道缓存的内容是不会存在磁盘中的。他只是在内核中的缓存中。







    展开全文
  • 有名管道创建与读写

    千次阅读 2011-09-27 10:47:23
    创建有名管道有两种方式: 一是在 shell 下交互地建立一个有名管道,二是在程序中使用系统函数建立有名管道。shell 方式下可使用 mknod 或 mkfifo 命令,下面命令使用 mknod 创建了一个有名管道: mknod...
    创建有名管道有两种方式:
    一是在 shell 下交互地建立一个有名管道,二是在程序中使用系统函数建立有名管道。shell 方式下可使用 mknod 或 mkfifo 命令,下面命令使用 mknod 创建了一个有名管道:
    mknod namepipe
    创建有名管道的系统函数有两个:mknod() 和 mkfifo() 。两个函数均定义在头文件 sys/stat.h 中,函数原型如下:
    引用
    #include <sys/types.h>
    #include <sys/stat.h>

    int mknod(const char *pathname, mode_t mode, dev_t dev);
      int mkfifo(const char *pathname, mode_t mode);

    函数 mknod() 参数中path 为创建的有名管道的全路径名;mod 为创建的有名管道的模式,指明其存取权限;dev 为设备值,该值取决于文件创建的种类,它只在创建设备文件时才会用到。这两个函数成功返回 0,失败则返回 -1。
    通过查看相关头文件,可以看到 mode_t 是 unsigned int  类型
    使用 mknod() 创建一个有名管道
    引用
    umask(0);
    if (mknod ("/tmp/fifo", S_IFIFO | 0666, 0== -1{
          perror("mknod error!");
          exit(1);
    }


    使用 mkfifo() 创建有名管道,mkfifo() 前两个参数的含义和 mknod() 相同
    引用
    umask(0);
    if (mkfifo ("/tmp/fifo", S_IFIFO | 0666, 0== -1{
          perror("mkfifo error!");
          exit(1);
    }


    “S_IFIFO | 0666" 指明创建一个有名管道且存取权限为 0666 ,即创建者、与创建者同组的用户、其他用户对该有名管道的访问权限都是可读可写。

    有名管道创建后就可以使用了,有名管道的和管道的使用方法基本相同。只是使用有名管道时,必须先调用 open() 将其打开,因为有名管道是一个存在硬盘上的文件,而管道是存在内存中的特殊文件。

    需要注意的是,调用 open() 打开有名管道的进程可能会被阻塞。但如果同时以读写方式 ( O_RDWR ) 打开,则一定不会导致阻塞;如果以只读方式 ( O_RDONLY ) 打开,则调用 open() 函数的进程将会被阻塞直到有写方打开管道;同样以写方式 ( O_WRONLY ) 打开也会阻塞直到有读方打开管道。
    展开全文
  • 有名管道

    千次阅读 2019-08-26 22:28:32
    有名管道(FIFO)不同于无名管道之处在于它提供了一个路径名与之关联,以 FIFO 的文件形式存在于文件系统中,这样,即使与 FIFO 的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过 FIFO 相互通信...

    无名管道只适用于有亲缘关系的进程间的通信,那么无亲缘关系的进程间如何通信呢?有名管道正是为了解决这个问题。有名管道(FIFO)不同于无名管道之处在于它提供了一个路径名与之关联,以 FIFO 的文件形式存在于文件系统中,这样,即使与 FIFO 的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过 FIFO 相互通信,因此,通过 FIFO 不相关的进程也能交换数据

    有名管道和无名管道的不同点:

    • FIFO 在文件系统中作为一个特殊的文件而存在,但 FIFO 中的内容却存放在内存中。
    • 当使用 FIFO 的进程退出后,FIFO 文件将继续保存在文件系统中以便以后使用。
    • FIFO 有名字,不相关的进程可以通过打开命名管道进行通信。

    有名管道和无名管道的相同点:

    • 假如 FIFO 里没有数据,调用 read() 函数从 FIFO 里读数据时 read() 也会阻塞。这个特点和无名管道是一样的。
    • 通信过程中,读进程退出后,写进程向命名管道内写数据时,写进程也会(收到 SIGPIPE 信号)退出。(以可读可写方式 open 管道时,此特点不存在。)
    • 调用 write() 函数向 FIFO 里写数据,当缓冲区已满时 write() 也会阻塞。

     创建有名管道

    #include <sys/types.h>
    #include <sys/stat.h>
    
    /* 创建有名管道 */
    int mkfifo(const char *pathname, mode_t mode);
    
    /* 参数:
        pathname: 路径名,即创建后有名管道的路径名
        mode: 文件的权限,与打开普通文件的 open() 函数中的 mode 参数相同
    */
    
    /* 返回值:
        0:成功。
        -1:失败,文件已存在,或出错。

    有名管道的操作

    有名管道在操作上和普通文件一样进行,如:open()、write()、read()、close() 等。但是,和无名管道一样,操作命名管道肯定要考虑默认情况下其阻塞特性。

    1.以只读和只写方式 open 管道,并且没有指定非阻塞标志 O_NONBLOCK 。则:

    • open() 以只读方式打开 FIFO 时,要阻塞到另一个进程为写而打开此 FIFO;
    • open() 以只写方式打开 FIFO 时,要阻塞到另一个进程为读而打开此 FIFO。
    • 通信过程中若写进程先退出了,就算命名管道里没有数据,调用 read() 函数从 FIFO 里读数据时不阻塞;若写进程又重新运行,则调用 read() 函数从 FIFO 里读数据时又恢复阻塞。

    2.以只读和只写方式 open 管道,并指定非阻塞标志 O_NONBLOCK 。则 open() 函数不会阻塞。

     非阻塞标志(O_NONBLOCK)打开的命名管道有以下特点:

    • 先以只读方式打开,如果没有进程已经为写而打开一个 FIFO, 只读 open() 成功,并且 open() 不阻塞。
    • 先以只写方式打开,如果没有进程已经为读而打开一个 FIFO,只写 open() 将出错返回 -1 。
    • read()、write() 读写命名管道中读数据时不阻塞。

    3.以可读可写方式 open 管道,则 open() 函数不会阻塞。

      特点:

    • read() 仍会阻塞,缓冲区满时,write() 也会阻塞;
    • 通信过程中,读进程退出后,写进程向命名管道内写数据时,写进程不会退出
    • 通信过程中若写进程先退出了,如果名管道里没有数据,调用 read() 函数从 FIFO 里读数据时会阻塞,与第一种情况不同。

    代码

    /* study.cpp 写端代码 */
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    
    int main()
    {
        int ret;
        ret = mkfifo("./FIFO", 0666);
        if(ret != 0)
        {
            perror("mkfifo");
        }
    
        int fd_w;
        printf("open之前\n");
    
        /* 1. 以只写方式打开有名管道 */
        //fd_w = open("./FIFO",O_WRONLY);
    
        /* 2. 以只写方式打开有名管道,非阻塞 */
        fd_w = open("./FIFO",O_WRONLY|O_NONBLOCK);
    
        /* 3. 以可读可写方式打开有名管道 */
        //fd_w = open("./FIFO",O_RDWR);
    
        printf("open之后\n");
        if(fd_w < 0)
        {
            perror("open");
            _exit(-1);
        }
    
        char str[64];
        int i = 0;
        while (i<5)
        {
            i++;
            memset(str,0,sizeof(str));
            sprintf(str,"%d: hello world!",i);
            printf("写:%s\n",str);
            write(fd_w,str,strlen(str)+1);
            sleep(2);
        }
        close(fd_w);
        return 0;
    }
    
    /* main.c 读端代码 */
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    
    int main()
    {
        int ret;
        ret = mkfifo("./FIFO", 0666);
        if(ret != 0)
        {
            perror("mkfifo");
        }
    
        int fd_r;
        printf("open之前\n");
    
    	/* 1. 以只写方式打开有名管道 */
        //fd_r = open("./FIFO",O_RDONLY);
    
    	/* 2. 以只写方式打开有名管道,非阻塞 */
        fd_r = open("./FIFO",O_RDONLY|O_NONBLOCK);
    
        /* 3. 以可读可写方式打开有名管道 */
        //fd_r = open("./FIFO",O_RDWR);
    
        printf("open之后\n");
        if(fd_r < 0)
        {
            perror("open");
            _exit(-1);
        }
    
        char str[64];
    	int i = 0;
        while (i<10)
        {
    		i++;
    		memset(str,0,sizeof(str));
            read(fd_r,str,sizeof(str));
    		printf("读:%s\n",str);
    		sleep(1);
        }
    	close(fd_r);
        return 0;
    }

    执行一下几种情况:

    1. 以只读和只写方式 open 管道,并且没有指定非阻塞标志 O_NONBLOCK:

    先在一个命令窗口执行 ./study ,可见阻塞在 open 函数:

     ⚙ lingyun@manjaro  ~/Document/CppCode/study  gcc study.cpp -o study
     ⚙ lingyun@manjaro  ~/Document/CppCode/study  gcc main.c -o main
     ⚙ lingyun@manjaro  ~/Document/CppCode/study  ./study               
    mkfifo: File exists
    open之前                    // open() 阻塞

    再在另一个命令窗口执行 ./main ,可见能够继续执行下去:

     ⚙ lingyun@manjaro  ~/Document/CppCode/study  ./main
    mkfifo: File exists
    open之前
    open之后
    读:1: hello world!
    读:2: hello world!
    读:                 //此处写进程已经退出,读进程的 read() 函数就不阻塞了
    读:
    读:
    读:1: hello world!  //此处写进程再次执行,读进程恢复阻塞特性(sleep(1)但得等 2s,说明 read() 阻塞)
    读:2: hello world!
    读:3: hello world!
    读:4: hello world!
    读:5: hello world!
     ⚙ lingyun@manjaro  ~/Document/CppCode/study  

    第一个命令窗口得以继续执行:

     ⚙ lingyun@manjaro  ~/Document/CppCode/study  ./study
    mkfifo: File exists
    open之前
    open之后                //读进程已经 open 了此管道,open() 不再阻塞
    写:1: hello world!
    写:2: hello world!
    ^C                      //此处退出写进程
     ✘ ⚙ lingyun@manjaro  ~/Document/CppCode/study  ./study         //再次执行写进程
    mkfifo: File exists
    open之前
    open之后
    写:1: hello world!
    写:2: hello world!
    写:3: hello world!
    写:4: hello world!
    写:5: hello world!
     ⚙ lingyun@manjaro  ~/Document/CppCode/study  

    2.以只读和只写方式 open 管道,并指定非阻塞标志 O_NONBLOCK:

    先执行只读程序:

     ⚙ lingyun@manjaro  ~/Document/CppCode/study  ./main
    mkfifo: File exists
    open之前
    open之后                    // 只读 open() 成功,并且 open() 不阻塞。
    读:                        // read() 读有名管道中读数据时不阻塞。
    读:
    读:
    读:
    读:
    读:
    读:
    读:
    读:
    读:
     ⚙ lingyun@manjaro  ~/Document/CppCode/study  

    先执行只写程序:

     ⚙ lingyun@manjaro  ~/Document/CppCode/study  ./study               
    mkfifo: File exists
    open之前
    open之后
    open: No such device or address        // 只写 open() 将出错返回 -1。
     ✘ ⚙ lingyun@manjaro  ~/Document/CppCode/study  
    

    3.以可读可写方式 open 管道:

     a. 测试在通信过程中退出读进程:

     ⚙ lingyun@manjaro  ~/Document/CppCode/study  ./main        //读进程
    mkfifo: File exists
    open之前
    open之后
    读:1: hello world!
    读:2: hello world!
    ^Z                        // 退出读进程
    [10]  + 9536 suspended  ./main
     ✘ ⚙ lingyun@manjaro  ~/Document/CppCode/study  
     ⚙ lingyun@manjaro  ~/Document/CppCode/study  ./study
    mkfifo: File exists
    open之前
    open之后
    写:1: hello world!
    写:2: hello world!
    写:3: hello world!        //虽然读进程退出,但写进程在向管道中写入数据时,并没有退出
    写:4: hello world!
    写:5: hello world!
     ⚙ lingyun@manjaro  ~/Document/CppCode/study  
    

     b. 测试在通信过程中先退出写进程:

     ⚙ lingyun@manjaro  ~/Document/CppCode/study  ./study
    mkfifo: File exists
    open之前
    open之后
    写:1: hello world!
    写:2: hello world!
    写:3: hello world!
    写:4: hello world!
    写:5: hello world!          //这里执行完后,写进程即退出
     ⚙ lingyun@manjaro  ~/Document/CppCode/study  
    
    ⚙ lingyun@manjaro  ~/Document/CppCode/study  ./main
    open之前
    open之后
    读:1: hello world!
    读:2: hello world!
    读:3: hello world!
    读:4: hello world!
    读:5: hello world!
                               //程序阻塞在这里,说明 read() 阻塞了

     

    展开全文
  • 有名管道的通信

    2017-03-25 17:31:04
    创建有名管道的进程叫做服务器进程,存取管道的其他进程叫做客户进程。通信双方必须首先创建有名管道后,才能打开管道进行读写。当文件不再需要时,要显示删除。 进程间使用有名管道实现通信时,必须有三次同步。 第...
  • 有名管道创建

    2011-08-24 22:55:50
    #include #include #include #include #include #include  int main(int argc, char **argv) {    mode_t mode = 0666;  if (argc != 2){
  • 管道有名管道

    2015-06-12 19:27:53
    之前老师一直说要自己写点东西,我总是想有很多人写了同样的东西,我何必还要再写呢?用的时候搜一搜就可以了。可是最近越来越发现把自己理解...1、管道创建 2、管道的关闭 3、管道的读写 特征:管道通信时半双工
  • linux有名管道

    2020-01-10 16:38:05
    有名管道是一个FIFO文件。 目录 特点: API: 例子: 扩展: 特点: 无名管道只能在父子/兄弟间进行通信,有名管道可以在无关进程之间交换数据。 有路径名与之关联,它以一种特殊设备文件形式存在于文件系统...
  • 进而有名管道(FIFO)应运而生,有名管道有一个路径名与之关联,所以允许无亲缘关系的进程访问同一个FIFO。以下具体介绍管道: 管道的创建:管道由函数 int pipe(int fd[2]) 创建,提供一个单向数据流,该函数返回...
  • 有名管道FIFO

    千次阅读 2013-10-26 14:19:36
    一、函数原型  #include #include int mkfifo( const char * filename, ... 功能:创建有名管道FIFO   参数:  filename:指定新创建FIFO的文件名称(包含路径名)  mode:指定FIFO的读写权限,和 op
  • linux编程--有名管道

    2014-08-18 14:29:36
    1.有名管道FIFO  管道如果无名,只能在共同血缘进程中使用... shelle命令和C程序都可以创建有名管道,其中创建有名管道的shell命令如下: 1)命令mknod创建管道 可以创建特殊类型的文件,其实用方式如下   /etc/
  • 有名管道例子

    千次阅读 2013-10-22 14:42:32
    测试系统:RedHat Linux 9.0 ... * 无名管道只能用于具有亲缘关系的进程之间,而有名管道可以在互不相关的两个进程间     * 实现彼此通信。要注意,FIFO严格按照先进先出的规则,对管道及FIFO的读总是从开始 
  • 在RTOS中,任务之间的通信手段有信号量、邮箱、消息队列,在Linux进程间通信,常用的包括:无名管道、有名管道、消息队列、信号、信号量、共享内存、套接字(socket)。下面分别看下这些通信方式,并有对应的例程...
  • 14.有名管道通信

    2019-09-21 12:20:29
    14.有名管道通信 有名管道有名管道又称为FIFO文件,因此我们对有名管道的操作可以采用操作文件的方法,如使用 open,read,write等. 有名管道的学习: 有名管道与其他文件的对比: FIFO文件在使用上和...
  • Linux之有名管道

    2013-11-09 20:44:30
     从linux中管道的创建过程我们可以看出,管道只可以在父子或者有血缘关系的 进程中进行通信,因为其以无名文件的形式存在文件系统中。为了克服这个问题,Linux 中发展了有名管道(FIFOS).有名管道以一种特殊的文件...
  • 无名管道和有名管道

    2019-09-25 22:33:46
    1)无名管道:管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)。 单独构成一种独立的文件系统:管道对于管道两端的进程而...
  • 3.是通过创建管道时,系统设置的文件描述符进行的。管道就是一个特殊的文件,这个文件只存在于内存中。在创建管道时 系统会为管道分配一个页面作为数据缓冲区,进行管道通信的两个进程通过读写这个缓冲区来进行...
  • Linux 高级编程 - 有名管道 FIFO

    千次阅读 2017-09-04 08:13:21
    Linux 高级编程 - 有名管道 FIFO
  • 有名管道双向通信 有名管道双向通信 同样的,使用一个“有名管道”是无法实现双向通信的,因为也涉及到抢数据的问题。 所以双向通信时需要两个管道。 图解: 关闭端口之后的图解: 当我们在一个进程里面既要进行读...
  • 有名管道实现进程间通信。

    千次阅读 2017-12-25 16:07:09
    通信的过程就是通过路径名来指出管道文件,然后在建立了管道联系之后两个进程就可以把它当做一个普通文件一样进行读写操作,但是有名管道是严格遵循FIFO的规则,也就是所谓的先进先出,如果从有名管道中读取数据的话...
  • 有名管道和无名管道的区别

    千次阅读 2017-04-26 14:47:26
    1)无名管道:管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)。  单独构成一种独立的文件系统:管道对于管道两端的进程...
  • 【Linux】管道文件(有名管道、无名管道) 多进程编程的目的就是为了同时完成多个任务。 例如:一个产品,一个软件,需要n个进程同时执行才能完成,而这些进程之间一定是有所联系的。 因此:多进程工作时,进程间...
  • 为了克服这个缺点,提出了命名管道(FIFO),也叫有名管道、FIFO 文件。 命名管道(FIFO)不同于无名管道之处在于它提供了一个路径名与之关联,以 FIFO 的文件形式存在于文件系统中,这样,即使与 FIFO 的创建...
  • linux无名管道和有名管道

    万次阅读 多人点赞 2017-04-07 16:27:04
    1)无名管道:管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)。  单独构成一种独立的文件系统:管道对于管道两端的进程而...
  • 进程通讯之有名管道

    千次阅读 2018-03-25 15:46:26
    进程通讯之有名管道 一、前言: 我们前面博客讲过,父子进程之间,对于文件操作的文件操作符是共享的,而对于进程的全局数据,堆区数据,栈区数据是不共享的,那么进程之间到底是怎么进行信息的传递的呢,具体的...
  • 多进程间通信之有名管道

    千次阅读 2014-09-02 17:17:04
    有名管道 FIFO 一个进程以读方式打开,另一个以写方式打开才能正常...有名管道是一个存在的特殊文件,可以在不同进程间通信,用户可以通过shell来创建有名管道(mknod 命令)。 命令管道的重用操作如下所示: ...
  • 有名管道与无名管道之间的区别

    千次阅读 2016-03-16 10:18:50
    1)无名管道:管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)。  单独构成一种独立的文件系统:管道对于管道两端的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,294
精华内容 2,917
关键字:

创建有名管道的过程