> 文档中心 > golang并发编程-01多进程编程-02管道

golang并发编程-01多进程编程-02管道

文章目录

  • 1 概述
  • 2 cmd的管道
    • 2.1 示例1 (利用管道输出命令结果)
    • 2.2 示例2(两条命令间的交互)
  • 3. 内存管道
  • 4. os管道

1 概述

概念:是一种半双工的(或者说单向的)通讯方式。它只能被用于父进程与子进程以及同祖先的子进程之间的通讯。
优点:简单
缺点:只能单向通讯以及对通讯双方关系上的严格限制

2 cmd的管道

2.1 示例1 (利用管道输出命令结果)

package helloimport ("bytes""fmt""io""os/exec")func Hello() {    //创建一个命令行cmd0 := exec.Command("PowerShell.exe","echo","-n","liuBei guanYu zhangFei")//创建一个能够获取此命令的输出的管道stdout0, err := cmd0.StdoutPipe()if err != nil{return}//start方法启动执行命令if err := cmd0.Start(); err != nil {fmt.Printf("Error: The command No.0 can not be startup: %s\n", err)return}//定义一个缓存var outputBuf0 bytes.Bufferfor {    //定义一个二进制切片tempOutput 来接收管道stdout0的数据tempOutput := make([]byte, 5)n, err := stdout0.Read(tempOutput)if err != nil {    //如果收到错误是结尾就跳出循环。if err == io.EOF {break} else {fmt.Printf("Error: Can not read data from the pipe: %s\n", err)return}}//如果管道中有数据,则写入缓存(outputBuf0)if n > 0 {outputBuf0.Write(tempOutput[:n])}}    //从缓存中读数fmt.Printf("%s\n", outputBuf0.String())}

2.2 示例2(两条命令间的交互)

package helloimport ("bufio""bytes""fmt""io""os/exec")func Apipe02(){cmd1 := exec.Command("PowerShell.exe","ls")cmd2 := exec.Command("PowerShell.exe","findstr.exe", "hello")//在cmd1代表的命令之上建立一个输出管道stdout1, err := cmd1.StdoutPipe()if err != nil {fmt.Printf("Error: Can not obtain the stdout pipe for command: %s\n", err)return}if err := cmd1.Start(); err != nil {fmt.Printf("Error: The command can not be startup: %s\n", err)return}//创建一个来自cmd1输出管道(stdout1)的输入管道outputBuf1outputBuf1 := bufio.NewReader(stdout1)//建立cmd2的输出管道stdin2,err := cmd2.StdinPipe()if err != nil {fmt.Printf("Error: Can not obtain the stdin pipe for command: %s\n", err)return}//cmd1输出管道(stdout1)的输入管道(outputBuf1)连接到cmd2的输出管道_,err = outputBuf1.WriteTo(stdin2)//定义一个缓存var outputBuf2 bytes.Buffer//将cmd2的标准输出指向缓存cmd2.Stdout = &outputBuf2//执行cmd2if err := cmd2.Start(); err != nil {fmt.Printf("Error: The command can not be startup: %s\n", err)return}//关闭cmd2的输出管道err = stdin2.Close()if err != nil {fmt.Printf("Error: Can not close the stdio pipe: %s\n", err)return}//等待cmd2 写完再去读if err := cmd2.Wait(); err != nil {fmt.Printf("Error: Can not wait for the command: %s\n", err)return}//读缓存fmt.Printf("%s\n", outputBuf2.String())}

3. 内存管道

  • 创建管道
reader, writer := io.Pipe()
  • 写入
 n,_err := writer.Write([]byte("hello"))

返回值n 是输入的字节数

  • 读取

创建一个切片以接收数据

buffer := make([]byte, 100)n,err = reader.Read(buffer)
  • 示例
reader, writer := io.Pipe()// 创建携程给writergo func() {_,err = writer.Write([]byte("hello"))if err != nil{return}defer writer.Close()}()buffer := make([]byte, 100)_,err = reader.Read(buffer)if err != nil {return err}fmt.Println(string(buffer))return nil

4. os管道

reader, writer, err := os.Pipe()

和内存管道用法相同