标签: goroutine

检测Go例程中断

有没有办法检测 go 例程在执行时是否被中断?我想要类似于InterruptedExceptionJava的东西: https ://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html

concurrency interrupt go interrupted-exception goroutine

-1
推荐指数
1
解决办法
757
查看次数

从 goroutine 之外停止 goroutine

我这里有一个 go 例程,需要在上下文过期时从外部 go 例程中停止。然而,当上下文过期时,go 例程不会停止,即使控制它的 go 例程停止,它也会继续运行。

package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ctxParent := context.Background()

    ch := make(chan bool)

    d := 5 * time.Second

    ctx, cancel := context.WithTimeout(ctxParent, d)
    defer cancel()
    go doSomething(ctx, ch)

    // go func() {
    select {

    // done
    case _ = <-ch:
        fmt.Println("goroutine finished")
    }

    fmt.Println("waiting 11 seconds on main thread, ending all go routines")

    time.Sleep(11 * time.Second)

    fmt.Println(">>>> END")
}

func doSomething(ctx context.Context, ch chan<- bool) {

    // …
Run Code Online (Sandbox Code Playgroud)

memory-leaks go goroutine

-1
推荐指数
1
解决办法
71
查看次数

进行整数数据竞争

关于 int 类型上 Go 数据竞争的问题。当我运行下面的程序时go run -race main.go

package main

import "fmt"

var i int

func main() {

    go func() {
        i = 10
    }()

    i = 5

    fmt.Println(i)
}
Run Code Online (Sandbox Code Playgroud)

它显示数据竞争警告。

~  $ go run -race main.go
5
==================
WARNING: DATA RACE
Write at 0x000000605908 by goroutine 7:
  main.main.func1()
      /home/dty1er/main.go:80 +0x3a

Previous write at 0x000000605908 by main goroutine:
  main.main()
      /home/dty1er/main.go:83 +0x56

Goroutine 7 (running) created at:
  main.main()
      /home/dty1er/main.go:79 +0x46
==================
Found 1 data race(s)
exit status 66
Run Code Online (Sandbox Code Playgroud)

我知道为什么会发生这种数据竞争; …

concurrency go goroutine

-1
推荐指数
1
解决办法
333
查看次数

在同一个 goroutine 中使用 Lock 和 Rlock

我正在使用 Go 中的 RWMutex 进行实验,我意识到可以使用以下代码实现这种行为:

  • goroutine 1 - RLock
  • goroutine 1 - 运行解锁
  • goroutine 2 - RLock
  • goroutine 2 - 运行解锁
  • goroutine 2 - 锁
  • goroutine 2 - 解锁
  • goroutine 1 - 锁
  • goroutine 1 - 解锁
package main

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

type RLockAndLockStruct struct {
    mu sync.RWMutex

    mapEx map[string]string
}

func main() {
    r := &RLockAndLockStruct{}
    r.mapEx = make(map[string]string)

    go r.RLockAndLockTest("test", "goroutine 1 - ")
    go r.RLockAndLockTest("test", "goroutine 2 - ")
    time.Sleep(4000 * time.Millisecond)
}

func …
Run Code Online (Sandbox Code Playgroud)

go goroutine

-1
推荐指数
1
解决办法
75
查看次数

将主协程上下文的副本传递给子例程上下文

我有一个 golang API 端点及其关联的上下文。

端点需要在幕后执行一些繁重的工作,因此我在主端点内创建一个新的子例程,然后返回响应本身。

为了处理上下文取消,我创建了一个后台上下文并将其作为新上下文传递给子例程。

问题是通过这样做,是的,我可以执行后台子例程,但是主上下文中用于跟踪的值,如请求 id、span id 等(大多数键对我来说是未知的)将是丢失的。

即使在响应发送到客户端之后,如何将父上下文传递给子例程而不取消执行。

编辑

我没有将任何值传递到上下文中。但最初我们传递的是跟踪所需的 request-id、span-id 等。这些信息都在上下文中。这是一个内部库,上下文是我们保存它的地方。

我知道这是使用上下文传递值的反模式,除了请求 ID 和其他对库而不是业务逻辑重要的值之外,不会传递任何值

go goroutine

-1
推荐指数
1
解决办法
996
查看次数

多个 goroutine 会同时调用 Conn 上的一个方法吗?

我的程序是这样的:

func handle(conn net.Conn) {
    msg := "hello, world!"
    for i:= 0; i< 100000; i++ {
        go func() {
            err := write(conn, msg)
        }
    }

}
func write(conn net.Conn, msg string) error {
    mlen := fmt.Sprintf("%04d", len(msg))

    _, err := conn.Write([]byte(mlen + msg))
    return err
}
Run Code Online (Sandbox Code Playgroud)

程序会同时运行100000个goroutine,所有的goroutine都会向同一个连接发送消息?我怀疑服务器会收到“hellohelloworldworld”之类的错误消息,但是在我的 Ubuntu 14.04LTS 中运行程序时没有问题。

那么,多个 goroutine 会同时调用 Conn 上的一个方法吗?

================================================== ========================

我怎样才能保持Write方法的原子性?

networking multithreading go goroutine

-2
推荐指数
1
解决办法
270
查看次数

Go中令人难以置信的并行任务的惯用解决方案是什么?

我目前正在盯着以下代码的增强版本:

func embarrassing(data []string) []string {
  resultChan := make(chan string)
  var waitGroup sync.WaitGroup
  for _, item := range data {
    waitGroup.Add(1)
    go func(item string) {
      defer waitGroup.Done()
      resultChan <- doWork(item)
    }(item)
  }

  go func() {
    waitGroup.Wait()
    close(resultChan)
  }()

  var results []string
  for result := range resultChan {
    results = append(results, result)
  }
  return results
}
Run Code Online (Sandbox Code Playgroud)

这只是在想我的想法.所有这一切都可以用其他语言表达为

results = parallelMap(data, doWork)
Run Code Online (Sandbox Code Playgroud)

即使在Go中不能轻易做到这一点,是不是还有比上面更好的方法呢?

concurrency channel go goroutine

-2
推荐指数
1
解决办法
357
查看次数

与Goroutines的基准

这里对Golang来说很新,并且在使用goroutines进行基准测试时遇到了问题.

我的代码在这里:

    type store struct{}

    func (n *store) WriteSpan(span interface{}) error {
        return nil
    }

    func smallTest(times int, b *testing.B) {
        writer := store{}
        var wg sync.WaitGroup
        numGoroutines := times
        wg.Add(numGoroutines)
        b.ResetTimer()
        b.ReportAllocs()
        for n := 0; n < numGoroutines; n++ {
            go func() {
                writer.WriteSpan(nil)
                wg.Done()
            }()
        }
        wg.Wait()
    }
    func BenchmarkTest1(b *testing.B) {
        smallTest(1000000, b)
    }

    func BenchmarkTest2(b *testing.B) {
        smallTest(10000000, b)
    }

Run Code Online (Sandbox Code Playgroud)

它看起来两个场景的运行时和分配应该是相似的,但运行它们会给我以下结果,这些结果有很大的不同.不知道为什么会这样?那些额外的分配来自哪里?

BenchmarkTest1-12 1000000000 0.26 ns/op 0 B/op 0 allocs/op

BenchmarkTest2-12 1 2868129398 ns/op 31872 B/op …

benchmarking go goroutine

-2
推荐指数
1
解决办法
229
查看次数

Goroutine中不包含关键字“ go”的比较

以下代码记录了一个错误:

致命错误:所有goroutine都在睡着-死锁!

package main

import "fmt"

func main() {
    ch := make(chan int)
    ch <- 1
    fmt.Println(<-ch)
}
Run Code Online (Sandbox Code Playgroud)

但是,当我将代码更改为:

package main

import "fmt"

func assign (ch chan int) {
    ch <- 1
}

func main() {
    ch := make(chan int)
    go assign (ch)

    fmt.Println(<-ch)
}
Run Code Online (Sandbox Code Playgroud)

打印出“ 1”。

然后我使用了缓冲通道:

package main

import "fmt"

func main() {
    ch := make(chan int, 2)
    ch <- 1
    ch <- 2
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}
Run Code Online (Sandbox Code Playgroud)

也可以打印“ 1”和“ 2”。

我对此情况有些困惑。提前致谢!

channel go goroutine

-2
推荐指数
1
解决办法
67
查看次数

如何确定从渠道接收的顺序?

考虑以下来自go 之旅的示例。

如何确定频道的接收顺序?为什么 x 总是从 gorouting 获得第一个输出?这听起来很合理,但我没有找到任何关于它的文档。我尝试添加一些睡眠,但仍然从第一次执行的 gorouting 中获取输入。

    c := make(chan int)
    go sumSleep(s[:len(s)/2], c)
    go sum(s[len(s)/2:], c)
    x, y := <-c, <-c // receive from c

    fmt.Println(x, y, x+y)
Run Code Online (Sandbox Code Playgroud)

睡眠是发送到通道之前。

channel go goroutine

-2
推荐指数
1
解决办法
78
查看次数