Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Golang并发,处理批量项目_Go_Concurrency_Channel - Fatal编程技术网

Golang并发,处理批量项目

Golang并发,处理批量项目,go,concurrency,channel,Go,Concurrency,Channel,我正在写一个程序来处理一个文本文件中的数百万行,500k需要5秒钟来验证文件,我想加快速度 我想在项目上循环并异步处理其中的x,然后等待响应,看看是否应该继续 我写了一些伪代码,我不确定我写的东西是否有意义,只是看起来很复杂,有没有一种更简单更优雅的方法 package main import ( "fmt" "sync" "time" ) func main() { // Need an object to loop over // need a l

我正在写一个程序来处理一个文本文件中的数百万行,500k需要5秒钟来验证文件,我想加快速度

我想在项目上循环并异步处理其中的x,然后等待响应,看看是否应该继续

我写了一些伪代码,我不确定我写的东西是否有意义,只是看起来很复杂,有没有一种更简单更优雅的方法

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    // Need an object to loop over
    // need a loop to read the response
    items := 100000
    concurrency := 20
    sem := make(chan bool, concurrency)
    returnChan := make(chan error)
    finChan := make(chan bool)

    var wg sync.WaitGroup

    go func() {
        for x := 0; x < items; x++ {
            // loop over all items
            // only do maxitems at a time
            wg.Add(1)
            sem <- true
            go delayFunc(x, sem, returnChan, &wg)
        }
        wg.Wait()
        finChan <- true
    }()

    var err error
    finished := false
    for {
        select {
        case err = <-returnChan:
            if err != nil {
                break
            }
        case _ = <-finChan:
            finished = true
            break
        default:
            continue
        }

        if err != nil || finished == true {
            break
        }
    }
    fmt.Println(err)
}

func delayFunc(x int, sem chan bool, returnChan chan error, wg *sync.WaitGroup) {
    //fmt.Printf("PROCESSING (%v)\n", x)
    time.Sleep(10 * time.Millisecond)
    <-sem // release the lock
    wg.Done()
    if x == 95000 {
        returnChan <- fmt.Errorf("Something not right")
    } else {
        returnChan <- nil
    }
}
主程序包
进口(
“fmt”
“同步”
“时间”
)
func main(){
//需要一个对象来循环
//需要一个循环来读取响应
项目:=100000
并发性:=20
sem:=make(chan bool,并发)
returnChan:=生成(chan错误)
finChan:=make(chan bool)
var wg sync.WaitGroup
go func(){
对于x:=0;xsem您的代码看起来不错,您实现了常用的Go模式。缺点是-您为每个项目生成worker goroutine。便宜时生成goroutine不是免费的。另一种方法是生成N个worker,并通过通道为他们提供项目。类似这样

package main
import (
    "fmt"
    "time"
)

func main() {
    items := 100
    concurrency := 10
    in := make(chan int)
    ret := make(chan error)

    for x := 0; x < concurrency; x++ {
        go worker(in, ret)
    }
    go func() {
        for x := 0; x < items; x++ {
            // loop over all items
            in <- x
        }
        close(in)
    }()
    for err := range ret {
        if err != nil {
            fmt.Println(err.Error())
            break
        }
    }
}
func worker(in chan int, returnChan chan error) {
    //fmt.Printf("PROCESSING (%v)\n", x)
    for x := range in {
        if x == 95 {
            returnChan <- fmt.Errorf("Something not right")
        } else {
            returnChan <- nil
        }
        time.Sleep(10 * time.Millisecond)
    }
    returnChan <- fmt.Errorf("The End")
}
主程序包
进口(
“fmt”
“时间”
)
func main(){
项目:=100
并发性:=10
in:=制造(成交量)
ret:=制造(更改错误)
对于x:=0;x在中,您的代码看起来很好,您实现了Go模式中常用的功能。缺点是-您为每个项目生成worker goroutine。在便宜的情况下生成goroutine不是免费的。另一种方法是生成N个worker,并通过通道向他们提供项目。类似这样的

package main
import (
    "fmt"
    "time"
)

func main() {
    items := 100
    concurrency := 10
    in := make(chan int)
    ret := make(chan error)

    for x := 0; x < concurrency; x++ {
        go worker(in, ret)
    }
    go func() {
        for x := 0; x < items; x++ {
            // loop over all items
            in <- x
        }
        close(in)
    }()
    for err := range ret {
        if err != nil {
            fmt.Println(err.Error())
            break
        }
    }
}
func worker(in chan int, returnChan chan error) {
    //fmt.Printf("PROCESSING (%v)\n", x)
    for x := range in {
        if x == 95 {
            returnChan <- fmt.Errorf("Something not right")
        } else {
            returnChan <- nil
        }
        time.Sleep(10 * time.Millisecond)
    }
    returnChan <- fmt.Errorf("The End")
}
主程序包
进口(
“fmt”
“时间”
)
func main(){
项目:=100
并发性:=10
in:=制造(成交量)
ret:=制造(更改错误)
对于x:=0;x在WaitGroup初始化之后,不要逐个添加到
wg
,而是执行类似于
wg.Add(items)
的操作。这不是您要问的问题,但这可能会创建一个难以捕获的错误,如“items+1”不同的go例程正在访问wg变量。为此,我不确定我的示例是否充分说明了我在做什么,我将读取相当大的文件,因此它将逐行缓冲,而不是逐个添加到
wg
,执行类似
wg.Add(items)的操作
在WaitGroup初始化之后。这不是您要问的问题,但这可能会创建一个难以捕获的错误,如“items+1”不同的go例程正在访问wg变量。为此,我不确定我的示例是否充分说明了我在做什么,我将读取相当大的文件,因此它将被逐行缓冲。感谢这个示例,我想我是如何使用
sem的啊感谢这个示例,我想我是如何使用
sem的