标签: goroutine

限制运行的go例程

我有要处理的网址列表,但我想一次运行最大数量的goroutine。例如,如果我有30个网址,那么我只希望10个goroutine并行工作。

我对此的尝试如下:

parallel := flag.Int("parallel", 10, "max parallel requests allowed")
flag.Parse()
urls := flag.Args()

var wg sync.WaitGroup
client := rest.Client{}

results := make(chan string, *parallel)

for _, url := range urls {
    wg.Add(1)
    go worker(url, client, results, &wg)
}

for res := range results {
    fmt.Println(res)
}

wg.Wait()
close(results)
Run Code Online (Sandbox Code Playgroud)

我的理解是,如果我创建一个大小为并行的缓冲通道,那么该代码将阻塞,直到我读出结果通道为止,这将取消阻塞我的代码并允许生成另一个goroutine。但是,此代码似乎在处理完所有网址后不会阻塞。有人可以向我解释如何使用通道限制运行的goroutine的数量吗?

go goroutine

5
推荐指数
1
解决办法
316
查看次数

C++ 1y标准是否被认为支持coroutine/goroutine?

我认为coroutine/goroutine在很多并发小任务必须快速执行的情况下非常有用.目前std::thread不能满足要求,因为它的成本很高.

我还认为只能通过C++库来支持coroutine/goroutine,它应该由语言的核心功能直接实现.因为coroutine/goroutine具有特殊的语义,在当前的C++标准中没有相应的概念.

如果我们添加一个新关键字cppgo,那么我们可以编写如下代码:

void f(int n)
{
    ...
}

int main()
{
    for (int i = 0; i < 10000; ++i)
    {
        cppgo f(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

多酷啊!

C++ 1y标准是否被认为支持coroutine/goroutine?

c++ standards coroutine goroutine c++14

4
推荐指数
1
解决办法
1680
查看次数

如何写出更好的双通道选择

在下面的代码中,有两个包含工作的通道A和B,在实际代码中它们是不同的结构,工作人员需要在退出之前排空两个通道.工人需要从两个渠道进来的信息.两个选择语句有效,但它非常笨拙.如果我添加default:以使它们无阻塞,则代码无法排空通道.是否有更好的方式来编写选择?

现在如果通道A没有工作,那么通道B也不会得到服务.要解决的另一个问题,但不是我的主要关注点.

测试以下代码的游乐场:

package main

import (
    "fmt"
    "time"
)

const (
    fillCount  = 10 // number of elements in each input channel
    numWorkers = 3  // number of consumers.
)

func Wait() {
    time.Sleep(2000 * time.Millisecond)
}

func fillChannel(work chan string, name string) {
    for i := 0; i < fillCount; i++ {
        work <- fmt.Sprintf("%s%d", name, i)
    }
    close(work) // we're finished
}

func doWork(id int, ch1 chan string, ch2 chan string, done chan …
Run Code Online (Sandbox Code Playgroud)

go goroutine

4
推荐指数
1
解决办法
96
查看次数

Golang,goroutines:恐慌:运行时错误:内存地址无效

我是golang的新手,并试图理解主要原则并使用chanels编写基于gouroutines的代码.

在我使用的其他语言中没有这样的乐器,我想知道这样的错误就像恐慌......

我的代码:

package main

import "fmt"
import (
    "time"
)
type Work struct {
    x,y,z int
}

func worker(in <-chan *Work, out chan<- *Work){
    for w := range in {
        w.z = w.x + w.y
        time.Sleep(time.Duration(w.z))
        out <-w
    }
}

func sendWork(in chan <- *Work){
    var wo *Work
    wo.x, wo.y, wo.z = 1,2,3
    in <- wo
    in <- wo
    in <- wo
    in <- wo
    in <- wo
}

func receiveWork(out <-chan *Work ) []*Work{
    var  slice []*Work
    for …
Run Code Online (Sandbox Code Playgroud)

channel go goroutine web

4
推荐指数
1
解决办法
2374
查看次数

Go:分配到nil map中的条目

我现在比较新,我在这个网站上搜索了这个问题,并且回答了问题,但是无法对我的案例实施这些答案.我有一个代码:

func receiveWork(out <-chan Work) map[string][]ChartElement {

    var countedData map[string][]ChartElement

    for el := range out {
        countedData[el.Name] = el.Data
    }
    fmt.Println("This is never executed !!!")

    return countedData
}
Run Code Online (Sandbox Code Playgroud)

这种方法之外的结构没有麻烦.也map不会执行(如测试恐慌这里).我知道麻烦在于将数据递增到结构中.

有一些goroutines,正在向通道发送数据,countedData方法rgabs all,应该像这样制作一个地图:

map =>
    "typeOne" => 
       [
         ChartElement,
         ChartElement,
         ChartElement,
       ],
    "typeTwo" => 
       [
         ChartElement,
         ChartElement,
         ChartElement,
       ]
Run Code Online (Sandbox Code Playgroud)

如何以正确的方式实现这种插入?

runtime-error go goroutine

4
推荐指数
1
解决办法
1万
查看次数

golang中的事件驱动模式

我正在使用golang来实现一个简单的事件驱动工作者.就像这样:

  go func() {
        for {
            select {
            case data := <-ch:
                time.Sleep(1)
                someGlobalMap[data.key] = data.value 
            }
        }
    }()
Run Code Online (Sandbox Code Playgroud)

主函数将创建几个goroutine,每个都将执行以下操作:

ch <- data
fmt.Println(someGlobalMap[data.key])
Run Code Online (Sandbox Code Playgroud)

正如你所看到的那样,因为我的工作人员需要一些时间来完成这项工作,所以我的主要功能将无效.我如何正确控制这个工作流程?

channel go goroutine

4
推荐指数
1
解决办法
1万
查看次数

goroutines执行顺序

我正在尝试理解这段代码,不确定为什么第二轮在第一轮之前执行.如果有人能真正帮助我,那就太棒了!

func sum(a []int, c chan int) {
   fmt.Println("summing: ", a)
   total := 0
   for _, v := range a {
      total += v
   }
   //fmt.Println("send to c",total)
   c <- total  // send total to c
}
func main() {
    //a := []int{7, 2, 8,134,23,23,1,23,1234,143, -9, 4, 0, 1234}

    c := make(chan int)

    go sum([]int{1,2,3}, c)
    go sum([]int{4,5,6}, c)

    x := <-c
    fmt.Println(x)
    x = <-c
    fmt.Println(x)
}
Run Code Online (Sandbox Code Playgroud)

OUTPUT:

summing:  [4 5 6]
15
summing:  [1 2 3]
6
Run Code Online (Sandbox Code Playgroud)

go goroutine

4
推荐指数
1
解决办法
2645
查看次数

如何根据goroutine返回的值停止goroutine

就像在这里我创建了一个游乐场样本:sGgxEh40ev,但无法让它工作.

quit := make(chan bool)
res := make(chan int)

go func() {
    idx := 0
    for {
        select {
        case <-quit:
            fmt.Println("Detected quit signal!")
            return
        default:
            fmt.Println("goroutine is doing stuff..")
            res <- idx
            idx++
        }
    }

}()

for r := range res {
    if r == 6 {
        quit <- true
    }
    fmt.Println("I received: ", r)
}
Run Code Online (Sandbox Code Playgroud)

输出:

goroutine is doing stuff..
goroutine is doing stuff..
I received:  0
I received:  1
goroutine is doing stuff..
goroutine is …
Run Code Online (Sandbox Code Playgroud)

channel go goroutine

4
推荐指数
1
解决办法
1609
查看次数

在Go中定期调用N个并发函数的最佳方法是什么?

在过去一天左右的时间里,我一直在努力解决问题,以找出创建N个并发函数的最佳方法,这些函数在Go中以相同的时间间隔定期调用。我希望能够指定任意数量的功能,让它们全部同时定期运行,并在指定的时间后结束它们。

现在,我有一个可行的解决方案,但是必须为每个并发函数创建一个新的代码。我也不确定如何正确使用sync.WaitGroup,因为我当前的实现导致程序永无休止(只是卡在了wg.Wait()的最后)

我简要地看了一下名为Multitick的自动报价包装器,但不确定如何实现它。也许Multitick可能是这里的解决方案?

func main() {
    N := 10

    var wg sync.WaitGroup
    wg.Add(N)

    quit := make(chan struct{})

    for i := 0; i < N; i++ {

        tick := time.NewTicker(500 * time.Millisecond)
        go func(t *time.Ticker) {

            for a := range tick.C {

                select {
                case <-quit:
                    break
                default:
                    fmt.Println(a) // do something on tick
                }
            }
            wg.Done()
        }(tick)
    }

    time.Sleep(10 * time.Second)
    close(quit)
    wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)

前往游乐场示范

因此,此解决方案有效,可以以适当的间隔同时执行所有代码,并在10秒后完成,但实际上并没有退出程序,最终挂在wg.Wait()行上。另外,每个并发函数调用都使用自己的代码-我可以通过任何方式使用一个“主”代码来运行所有函数吗?

提前致谢!这是我第一次真正研究Go的并发性。

go ticker file-writing goroutine channels

4
推荐指数
1
解决办法
57
查看次数

fasthttp.Client结合goroutine的正确使用

我是 Go 新手,正在寻找使用 goroutine 的正确net/http方法fasthttp。不幸的是,那里没有很多fasthttp客户示例。

我找到了以下代码:(示例1

package main

import (
    "bufio"
    "fmt"
    "github.com/valyala/fasthttp"
    "log"
    "net"
    "os"
    "sync"
    "time"
)

func grabPage(fastClient *fasthttp.Client, i int, wg *sync.WaitGroup) {
    defer wg.Done()
    _, body, err := fastClient.GetTimeout(nil, "https://en.wikipedia.org/wiki/Immanuel_Kant", time.Duration(time.Second*20))
    if err != nil {
        log.Fatal(err)
    }
    f, err := os.Create(fmt.Sprintf("./data/%d.txt", i))
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()
    w := bufio.NewWriter(f)
    w.Write(body)
}

func main() {
    var wg sync.WaitGroup
    total := 500

    c …
Run Code Online (Sandbox Code Playgroud)

client http go goroutine fasthttp

4
推荐指数
1
解决办法
4942
查看次数