标签: goroutine

Go如何决定何时在goroutines之间切换?

我很好奇Go语言如何安排goroutines.它是仅在通道请求和I/O期间切换还是具有周期性协程切换循环?

concurrency go goroutine

6
推荐指数
1
解决办法
1586
查看次数

什么是同步goroutines的首选方式

我有一个昂贵的功能,我应用于切片的所有项目.我正在使用goroutines来处理它,每个goroutine处理切片的一个项目.

func Huge(lst []foo) {
  for _, item := range lst {
     go performSlow(item)
  }

  // How do I synchronize here ?
  return someValue(lst)
}
Run Code Online (Sandbox Code Playgroud)

问题是,如评论所示,在调用someValue函数之前,等待所有goroutine完成工作的首选方法是什么?传递一个频道performSlow并等到每个人都写到它的工作,但它似乎有点过分:

func Huge(lst []foo) {
  ch := make(chan bool)

  for _, item := range lst {
     go performSlow(item, ch)  // performSlow does its job, then writes a dummy value to ch
  }

  for i := range lst {
     _ = <-ch
  }

  return someValue(lst)
}
Run Code Online (Sandbox Code Playgroud)

是否有更好的(即更有效和/或更惯用)的方式来做到这一点?

synchronization go goroutine

6
推荐指数
1
解决办法
994
查看次数

goroutines如何运作?

我正在关注Go Tour,当涉及到goroutines时我有点卡住了.我知道他们非常轻量级,每次goroutine阻止,另一个将开始,但我无法理解这个例子实际如何工作:

package main

import (
    "fmt"
    "time"
)

func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(1000 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    go say("world")
    say("hello")
}
Run Code Online (Sandbox Code Playgroud)

Playground

据我所知,一个goroutine是针对具有参数"world"的say函数启动的,但据我所知,应该打印"world"五次并且"hello"一次.但是我不明白为什么输出是这样的:

hello
world
hello
world
hello
world
hello
world
hello
Run Code Online (Sandbox Code Playgroud)

从我对其他语言的线程的有限理解,输出应该是这样的:

hello
world
world
world
world
world
Run Code Online (Sandbox Code Playgroud)

或者像这样:

world 
world
world
hello
world
world
Run Code Online (Sandbox Code Playgroud)

为什么第二行也执行五次?go语句下面的任何内容都会归类为go例程的一部分吗?

下一张幻灯片还显示了我无法再次回头看的内容:

package main

import "fmt"

func sum(a []int, c chan int) {
    sum := 0 …
Run Code Online (Sandbox Code Playgroud)

concurrency go goroutine

6
推荐指数
1
解决办法
1132
查看次数

关于Goroutines的Golang记忆泄漏

我有一个持续运行的Go程序,完全依赖于goroutines + 1 manager线程.主线程只调用goroutines然后休眠.

有内存泄漏.该程序使用越来越多的内存,直到它耗尽所有16GB RAM + 32GB SWAP,然后每个goroutine恐慌.它实际上是操作系统内存导致恐慌,通常恐慌是fork/exec ./anotherapp: cannot allocate memory我尝试执行时anotherapp.

发生这种情况时,所有工作线程都会发生混乱并恢复并重新启动.所以每个goroutine都会惊慌失措,恢复并重新启动......此时内存使用量不会减少,即使现在几乎没有任何分配,它仍然保持在48GB.这意味着所有goroutine总是会因为没有足够的内存而恐慌,直到整个可执行文件被杀死并完全重启.

整个事情大概是50,000行,但实际问题区域如下:

type queue struct {
    identifier string
    type bool
}

func main() {

    // Set number of gorountines that can be run
    var xthreads int32 = 10
    var usedthreads int32
    runtime.GOMAXPROCS(14)
    ready := make(chan *queue, 5)

    // Start the manager goroutine, which prepared identifiers in the background ready for processing, always with 5 waiting to go
    go manager(ready)

    // Start creating …
Run Code Online (Sandbox Code Playgroud)

multithreading memory-leaks go goroutine

6
推荐指数
1
解决办法
2244
查看次数

测试Golang Goroutine

我一直在寻找周围,但到目前为止只进行了类似的文章写到这里通过Ariejan德弗鲁姆.

我想知道我是否可以将goroutine引入单元测试,以便它可以精确计算正在运行的goroutine的并发数量,并且可以告诉我它们是否正确地产生了我所说的数字goroutine.

我有以下代码例如..

import (
    "testing"
    "github.com/stretchr/testify/assert"
)

func createList(job int, done chan bool) {
    time.Sleep(500)
    // do something
    time.Sleep(500)
    done <- true
    return
}

func TestNewList(t *testing.T) {
  list := NewList()
  if assert.NotNil(t, list) {
    const numGoRoutines = 16
    jobs := make(chan int, numGoRoutines)
    done := make(chan bool, 1)

    for j := 1; j <= numGoRoutines; j++ {
        jobs <- j
        go createList(j, done)
        fmt.Println("sent job", j)
    }
    close(jobs)
    fmt.Println("sent all jobs")
    <-done
}
Run Code Online (Sandbox Code Playgroud)

tdd unit-testing go goroutine

6
推荐指数
1
解决办法
5979
查看次数

在多个goroutine之间共享的Golang struct中,非共享成员是否需要互斥保护?

我有一个在多个goroutine之间共享的Golang结构.对于结构成员的并发访问,有互斥锁sync.RWMutex.对于由单个goroutine访问的struct成员,是否需要互斥保护?

例如,在下面的代码中,一个单独的writer goroutine访问成员shared.exclusiveCounter,没有任何锁定保护.这是正确/安全吗?或者是否需要互斥锁,因为整个结构由多个goroutines通过共享指针访问?

package main

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

func main() {
    s := &shared{mutex: &sync.RWMutex{}}

    readerDone := make(chan int)
    writerDone := make(chan int)

    go reader(s, readerDone)
    go writer(s, writerDone)

    <-readerDone
    <-writerDone
}

type shared struct {
    mutex            *sync.RWMutex
    sharedCounter    int // member shared between multiple goroutines, protected by mutex
    exclusiveCounter int // member exclusive of one goroutine -- is mutex needed?
}

func (s *shared) readCounter() int {
    defer s.mutex.RUnlock()
    s.mutex.RLock()
    return s.sharedCounter
}

func (s *shared) …
Run Code Online (Sandbox Code Playgroud)

concurrency synchronization mutex go goroutine

6
推荐指数
1
解决办法
4103
查看次数

goroutines和boost.fiber之间的区别

我刚开始看看go以及go的工作原理.我只是想知道你是否可以在C++中实现相同的东西并找到boost.fiber.goroutines和boost纤维有什么区别?你能用C++中的那些光纤实现goroutine吗?

c++ concurrency boost go goroutine

6
推荐指数
1
解决办法
2584
查看次数

如何在golang程序中避免死锁?

这是我的程序产生死锁,我该如何避免它以及处理这种情况的推荐模式是什么.

问题是在超时后如何检测到我的频道上没有读卡器?

var wg sync.WaitGroup

func main() {   
    wg.Add(1)
    c := make(chan int)
    go readFromChannel(c, time.After(time.Duration(2)*time.Second))
    time.Sleep(time.Duration(5) * time.Second)
    c <- 10
    wg.Wait()
}

func readFromChannel(c chan int, ti <-chan time.Time) {
    select {
    case x := <-c:
        fmt.Println("Read", x)
    case <-ti:
        fmt.Println("TIMED OUT")
    }
    wg.Done()
}
Run Code Online (Sandbox Code Playgroud)

go goroutine

6
推荐指数
2
解决办法
4608
查看次数

等待多个goroutines的结果

我正在寻找一种方法来异步执行go中的两个函数,它返回不同的结果和错误,等待它们完成并打印两个结果.另外,如果函数返回错误之一,我不想等待另一个函数,只打印错误.例如,我有这个功能:

func methodInt(error bool) (int, error) {
    <-time.NewTimer(time.Millisecond * 100).C
    if error {
        return 0, errors.New("Some error")
    } else {
        return 1, nil
    }
}

func methodString(error bool) (string, error) {
    <-time.NewTimer(time.Millisecond * 120).C
    if error {
        return "", errors.New("Some error")
    } else {
        return "Some result", nil
    }
}
Run Code Online (Sandbox Code Playgroud)

这里https://play.golang.org/p/-8StYapmlg就是我实现它的方式,但我认为它有太多的代码.它可以通过使用接口{}来简化,但我不想这样做.我想要更简单的东西,例如,可以使用async/await在C#中实现.可能有一些库可以简化这种操作.

更新:感谢您的回复!我得到多快帮助真是太棒了!我喜欢WaitGroup的用法.它显然使代码对更改更加健壮,因此我可以轻松地添加另一个异步方法,而不会最终改变方法的确切数量.但是,与C#相比,仍有如此多的代码.我知道在go中我不需要明确地将方法标记为异步,使它们实际上返回任务,但是方法调用看起来要简单得多,例如,考虑这个链接实际上也需要捕获异常 顺便说一下,我找到了在我的任务中,我实际上不需要知道我想要运行异步的函数的返回类型,因为无论如何它将被整理到json,现在我只是在go-kit的端点层调用多个服务.

channel go goroutine

6
推荐指数
2
解决办法
3658
查看次数

Golang http server 在启动无限循环的goroutine时阻塞

正如我从 golang 文档中了解到的,如果我将 runtime.GOMAXPROCS(8) 设置为 8 核(intel i7)的 cpu,然后启动一个无限循环的 goroutine,其他 gorutines 不应该被阻塞,因为有足够的线程和 goprocs。但是在使用 net/http 包时就不是这样了,一个无限循环的 goroutine 会在几次调用后阻塞 http 服务器。任何人都可以帮助解释原因吗?

  1. 如果我注释“无限循环”这一行,在服务器之后启动客户端,客户端将输出1000个星号;但是如果我启用 goroutine,客户端会在打印几个星号后阻塞
  2. 我已经尝试在 goroutine 中添加 runtime.LockOSThread() ,似乎不起作用
  3. 我的环境:osx 10.10, go version go1.3.1 darwin/amd64

服务器代码:

package main

import (
    "fmt"
    "log"
    "net/http"
    "runtime"
)

func myHandler(w http.ResponseWriter, req *http.Request) {
    w.Write([]byte("hello"))
}

func infiniteloop() {
    for {

    }
}

func main() {
    // set max procs for multi-thread executing
    runtime.GOMAXPROCS(runtime.NumCPU())

    // print GOMAXPROCS=8 on my computer
    fmt.Println("GOMAXPROCS=", runtime.GOMAXPROCS(-1))
    http.Handle("/", http.HandlerFunc(myHandler))

    // uncomment …
Run Code Online (Sandbox Code Playgroud)

http block go goroutine

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