简体   繁体   English

Go中的缓冲通道

[英]Buffered channels in Go

I am working on a project using raspberry pi and an arduino. 我正在使用树莓派和arduino开发一个项目。 I'm writing a GO program on the raspberry pi to receive UART data from the Arduino at 115200 baud rate every second. 我正在树莓派上编写一个GO程序,以每秒115200的波特率从Arduino接收UART数据。 The raspberry pi reads the UART data, saves it to a file (based on the value to either file1 or file2 , etc), and then send the file to ftp server. 树莓派读取UART数据,将其保存到文件(基于file1file2等的值),然后将文件发送到ftp服务器。

Since uploading to server might take time depending on network I want to use go concurrency so that UART reading and saving to file are not interrupted. 由于上传到服务器可能需要花费一些时间,具体取决于网络,因此我想使用go并发性,以确保UART读取和保存到文件不会中断。 The following is pseudocode (skeleton) that I am trying to apply. 以下是我尝试应用的伪代码(骨架)。 My thinking in the code is the filepaths will be buffered in the channel sequencially and the upload is performed in the same order. 我在代码中的想法是文件路径将依次在通道中缓冲,并且上传是以相同顺序执行的。 Am I doing it correctly? 我做得对吗? Is there a better way to approach the problem? 有没有更好的方法来解决此问题?

package main

import "strings"

func SendFile(filePath string) {

}
// based on the value of the data, SaveToFile saves the data to either file1, file2 or file3
func SaveToFile(uartData []string) filePath string {

    return filePath
}

func main() {


    ch := make(chan string, 1000)

    //uartInit initialization goes here
    uart := uartInit()

    //infinite loop for reading UART...
    for {
        buf := 1024 // UART buffer
        data := uart.Read(buf)
        uartData = strings.Split(string(buf), " ")

        //channel receives filepath 
        ch <- SaveToFile(uartData)

        //channel sends filepath
        go SendFile(<-ch)

    }
}

You are writing one string to the channel, and reading it back. 您正在将一个字符串写入通道,然后将其读回。 The sendFile() runs in a different goroutine, but there is no need for the channel in the way you're using it. sendFile()在不同的goroutine中运行,但是不需要您使用通道的方式。 You could simply do 你可以做

 fname:= SaveToFile(uartData)
 go SendFile(fname)

However, I don't think this is what you want to do. 但是,我不认为这是您想要做的。

Instead, you should have a goroutine in which you read data from the UART, and write to a buffered channel. 相反,您应该具有一个goroutine,可以在其中从UART读取数据并写入缓冲通道。 Listening to that channel is another goroutine that writes blocks of data to a file. 监听该通道是另一个goroutine,它将数据块写入文件。 When it is ready to be sent, create a third goroutine to send the file. 准备好发送时,创建第三个goroutine发送文件。

After reading the comments and some online resources the following approach seems to work fine so far. 阅读评论和一些在线资源后,到目前为止,以下方法似乎可以正常工作。 The first 8 minutes in this video was quite helpful to understand the concept. 视频的前8分钟非常有助于理解这一概念。 The defer close(ch) is something I'm uncertain, though. 不过,不确定defer close(ch)是什么。

package main

import "strings"

func SendFile(ch chan string) {
  for filePath := range ch {
   //upload file here
  }

}

func SaveToFile(uartData []string) filePath string {

    return filePath
}

func main() {


    ch := make(chan string, 1000)
    defer close(ch)
    go SendFile(<-ch)

    uart := uartInit()


    for {

        data := uart.Read(buf)
        uartData = strings.Split(string(buf), " ")
        ch <- SaveToFile(uartData)

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM