标签: goroutine

我可以强制终止goroutine而不等待它返回吗?

让我举一个例子:

func WaitForStringOrTimeout() (string, error) {
  my_channel := make(chan string)
  go WaitForString(my_channel)

  select {
  case found_string := <-my_channel:
    return found_string, nil
  case  <-time.After(15 * time.Minute):
    return nil, errors.New("Timed out waiting for string")
  }
}
Run Code Online (Sandbox Code Playgroud)

在这个简单的例子中,我有一些函数WaitForString,它会阻塞一段时间并最终返回一个字符串.我想用这个代码包装WaitForString,该代码返回相同的字符串或超时并带有错误.

如果快速找到一个字符串,是否还有一个goroutine在某处运行15分钟的睡眠声明,或者这个垃圾是以某种方式收集的?

如果发生超时并且从未找到字符串,那么仍然存在运行WaitForString的goroutine,即使没有其他例程可以观察它的输出吗?如果WaitForString分配了大量内存但从不返回怎么办?

有没有什么方法可以让WaitForString()意识到超时发生并放弃?

concurrency select garbage-collection go goroutine

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

像erlang一样可以透明地跨多个主机生成进程吗?

据说如果配置erlang并设置了cookie,那么erlang的进程可以在不同的机器上运行,这对调用者来说是透明的.这样的goroutine可能会运行吗?

erlang go goroutine

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

为什么goroutine泄漏

我在第30页阅读了Twelve Go Best Practices和遭遇以及有趣的例子.

func sendMsg(msg, addr string) error {
    conn, err := net.Dial("tcp", addr)
    if err != nil {
        return err
    }
    defer conn.Close()
    _, err = fmt.Fprint(conn, msg)
    return err
} 

func broadcastMsg(msg string, addrs []string) error {
    errc := make(chan error)
    for _, addr := range addrs {
        go func(addr string) {
            errc <- sendMsg(msg, addr)
            fmt.Println("done")
        }(addr)
    }

    for _ = range addrs {
        if err := <-errc; err != nil {
            return err …
Run Code Online (Sandbox Code Playgroud)

go goroutine

5
推荐指数
2
解决办法
3609
查看次数

是否需要同步?

我在对象中定义了一个变量(r.something)

func (r *Runner) init() {
  r.something = make(map[string]int)
  r.something["a"]=1

  go r.goroutine()
}
Run Code Online (Sandbox Code Playgroud)

而r.goroutine使用存储在r.something中的值而没有同步.除了r.goroutine()之外,没有其他人会读/写这个值

没有同步可以安全吗?

换句话说:我想 goroutine start 之前重新使用从其他地方初始化的goroutine中的一些变量.这样安全吗?

附加问题:在r.goroutine()完成之后,我希望能够使用来自其他地方的r.something(没有与其他goroutine的读/写重叠).它也安全吗?

go goroutine

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

Goroutines和多种类型的频道

我是Go的新手,试图找出同时从中提取信息的最佳方式REST API.目的是对a进行多个并发调用API,每次调用返回不同类型的数据.

我目前有:

s := NewClient()
c1 := make(chan map[string]Service)
c2 := make(chan map[string]ServicePlan)
c3 := make(chan map[string]ServiceInstance)
c4 := make(chan map[string]ServiceBinding)
c5 := make(chan map[string]Organization)
c6 := make(chan map[string]Space)

go func() {
    c1 <- GetServices(s)
}()

go func() {
    c2 <- GetServicePlans(s)
}()

go func() {
    c3 <- GetServiceInstances(s)
}()

go func() {
    c4 <- GetServiceBindings(s)
}()

go func() {
    c5 <- GetOrganizations(s)
}()

go func() {
    c6 <- GetSpaces(s)
}()

services := <- c1 …
Run Code Online (Sandbox Code Playgroud)

channel go goroutine

5
推荐指数
2
解决办法
2553
查看次数

流程与Golang中的Goroutine一样吗?

对于以下代码:

func main() {
    goRtns := runtime.NumGoroutine()
    fmt.Println("goroutines:", goRtns)
}
Run Code Online (Sandbox Code Playgroud)

输出为1。但这是在“过程”中,没有goroutines被明确调用:

“在计算中,进程是正在执行的计算机程序的实例。它包含程序代码及其当前活动。根据操作系统(OS),进程可能由多个执行线程组成,这些线程执行指令同时进行。”

同样来自克里希纳·桑达拉姆(Krishna Sundarram)出色的“ goroutines如何工作”博客文章:http : //blog.nindalf.com/how-goroutines-work/

“创建goroutine不需要太多的内存,仅需要2kB的堆栈空间。它们可以通过根据需要分配和释放堆存储来增长。”

那么我的问题是:运行时库将正在运行的代码实例(我简单的main.go函数)计为goroutine。我是否假定父进程被视为go例程,并且具有相同的内存分配,垃圾回收等规则?假设读取有关goroutine执行的事实与运行它的总体go进程类似,是否明智?关于上面关于goroutine的第二个引号,这听起来像是一个程序在执行程序时增大/缩小其堆栈空间的过程,这是编程的标准范例。

go流程和例程是否共享相同的规则?还是我只是缺少有关报告的goroutine数量的信息。

memory process go goroutine

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

如何在golang中使用gin-gonic服务器编写流API?试过c.Stream没工作

我想在golang中使用gin-gonic服务器创建一个流API.

func StreamData(c *gin.Context) {
    chanStream := make(chan int, 10)
    go func() {for i := 0; i < 5; i++ {
        chanStream <- i
        time.Sleep(time.Second * 1)
    }}()
    c.Stream(func(w io.Writer) bool {
        c.SSEvent("message", <-chanStream)
        return true
    })
}

router.GET("/stream", controller.StreamData)
Run Code Online (Sandbox Code Playgroud)

但是当我试图击中端点时,它只是卡住而没有响应.有人使用流功能,以便他/她可以指出我可能正在做的错误.谢谢!

api streaming go goroutine go-gin

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

使用goroutines处理值并将结果收集到切片中

我最近正在探索Go,goroutines如何工作使我感到困惑。

我尝试使用goroutines将之前编写的代码移植到Go中,但出现fatal error: all goroutines are asleep - deadlock!错误。

我正在尝试使用goroutines处理列表中的项目,然后将处理后的值收集到新列表中。但是我在“聚会”部分遇到了问题。

码:

sampleChan := make(chan sample)
var wg sync.WaitGroup

// Read from contents list
for i, line := range contents {
    wg.Add(1)
    // Process each item with a goroutine and send output to sampleChan
    go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg)
}
wg.Wait()

// Read from sampleChan and put into a slice
var sampleList []sample
for s := range sampleChan {
    sampleList = append(sampleList, s)
}
close(sampleChan)
Run Code Online (Sandbox Code Playgroud)

从goroutine收集结果的正确方法是什么?

我知道切片不是线程安全的,所以我不能让每个goroutine仅追加到切片中。

go slice goroutine

5
推荐指数
2
解决办法
2112
查看次数

这里有资源泄漏吗?

func First(query string, replicas ...Search) Result {
  c := make(chan Result)
  searchReplica := func(i int) {
    c <- replicas[i](query)
  }
  for i := range replicas {
    go searchReplica(i)
  }
  return <-c
}
Run Code Online (Sandbox Code Playgroud)

这个函数来自Rob Pike在2012年的并发模式上的幻灯片.我认为这个函数存在资源泄漏.当第一个发送和接收对发生在通道c上后,函数返回,其他的例程尝试在通道c上发送.所以这里有资源泄漏.谁知道golang好可以证实这一点?如何使用什么样的golang工具检测这种泄漏?

concurrency channel go goroutine

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

在我的代码中安全完成goroutine的正确方法是什么?

我正在编写一个简单的tcp服务器,goroutine模型非常简单:

一个goroutine负责接受新的连接。对于每个新连接,将启动三个goroutine:

  1. 一读
  2. 一种用于处理和处理应用程序逻辑
  3. 一个写

目前,一台服务器最多可服务1000个用户,因此我不会尝试限制goroutine的数量。

for {
    conn, err := listener.Accept()
    // ....
    connHandler := connHandler{
        conn:      conn,
        done:      make(chan struct{}),
        readChan:  make(chan string, 100),
        writeChan: make(chan string, 100),
    }
    // ....
    go connHandler.readAll()    
    go connHandler.processAll() 
    go connHandler.writeAll()   
}
Run Code Online (Sandbox Code Playgroud)

我使用done通道通知所有三个通道完成,当用户注销或永久性网络错误发生时,done通道将被关闭(使用sync.Once确保关闭仅发生一次):

func (connHandler *connHandler) Close() {
    connHandler.doOnce.Do(func() {
        connHandler.isClosed = true
        close(connHandler.done)
    })
}
Run Code Online (Sandbox Code Playgroud)

下面是writeAll()方法的代码:

func (connHandler *connHandler) writeAll() {
    writer := bufio.NewWriter(connHandler.conn)

    for {
        select {
        case <-connHandler.done:
            connHandler.conn.Close()
            return
        case msg := …
Run Code Online (Sandbox Code Playgroud)

channel go goroutine

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