标签: goroutine

同时收听多个 go 频道

假设我有一个 go 接收通道。有没有一种方法可以让我同时收听所有内容?例如:

channels := make([]<-chan int, 0, N)
// fill the slice with channels
for _, channel := range channels {
  <-channel
}
Run Code Online (Sandbox Code Playgroud)

这是我能做到的最接近的事情。但是,此实现取决于切片元素的顺序。

为了清楚起见,我不需要知道 go 通道的值。我只需要知道他们都完成了。

channel go goroutine

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

在 Golang 中使用上下文超时停止正在运行的函数

我想利用 golang 中的上下文在超时时用于取消。

代码:

package main

import "fmt"
import "time"
import "context"

func F(ctx context.Context) error {
  ctx, cancel := context.WithTimeout(ctx,3*time.Second)
  defer cancel()
  for i:=0;i<10;i++ {
    time.Sleep(1 * time.Second)
    fmt.Println("No: ",i)
  }
  select {
    case <-ctx.Done():
      fmt.Println("TIME OUT")
      cancel()
      return ctx.Err()
    default:
      fmt.Println("ALL DONE")
      return nil
  }
}

func main() {
  ctx := context.Background()
  err := F(ctx)
  if err != nil {
    fmt.Println(err)
  }else {
    fmt.Println("Success")
  }
}
Run Code Online (Sandbox Code Playgroud)

期望:上面的代码应该在 counter 处停止运行循环2,因为超时为 3 秒,循环每次运行 1 秒。所以我期待这样的事情:

No:  0
No: …
Run Code Online (Sandbox Code Playgroud)

go goroutine

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

在另一个例程中调用 SetReadDeadline 的用法是否正确?

在大多数示例中,SetReadDeadline在调用 之前调用net.Conn.Read()

在我的程序中,为了中断我的net.Conn.Read(),我调用net.Conn.SetReadDeadline(time.Now())另一个线程/例程。这是正确的方法吗?

谢谢。

go goroutine

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

上下文因超时而取消,但计算并未中止?

尝试了解 go 上下文取消如何中止后续代码的执行

实验详情:

  1. main 函数有一个超时的上下文2sec
  2. main funcsum在单独的 go-routine 中调用另一个 func - 它为1sectest-run-1 和4sectest-run-2休眠
  3. 让 main 休眠以便3sec让 spin go 例程完成执行
package main

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

func main() {

    c := context.Background()
    childCtx, cancel := context.WithTimeout(c, 2*time.Second)
    defer cancel()

    ch := make(chan int, 1)
    go sum(5, 6, ch)

    var msg string

    select {
    case <-childCtx.Done():
        msg = "return from ctx done channel"
    case res := <-ch:
        msg = …
Run Code Online (Sandbox Code Playgroud)

go goroutine go-context

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

如何使用goroutine来执行for循环?

假设我有一个像这样的切片:

stu = [{"id":"001","name":"A"} {"id":"002", "name":"B"}]也许还有更多这样的元素。切片内部是一个长字符串,我想使用 json.unmarshal 来解析它。

type Student struct {
   Id   string `json:"id"`
   Name string `json:"name"`
}

studentList := make([]Student,len(stu))
for i, st := range stu {
   go func(st string){
      studentList[i], err = getList(st)
      if err != nil {
         return ... //just example
      }
   }(st)
}
//and a function like this
func getList(stu string)(res Student, error){
   var student Student
   err := json.Unmarshal(([]byte)(stu), &student)
   if err != nil {
      return
   }
   return &student,nil
}
Run Code Online (Sandbox Code Playgroud)

我得到了 nil 结果,所以我想说 goroutine …

go goroutine

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

goroutine 启动前初始化sync.WaitGroup

我有以下代码作为测试的一部分:

    expected := 10
    var wg sync.WaitGroup
    for i := 0; i < expected; i++ {
        go func(wg *sync.WaitGroup) {
            wg.Add(1)
            defer wg.Done()
            // do something
        }(&wg)
    }
    wg.Wait()
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,我panic: Fail in goroutine after TestReadWrite has completed在运行“go test”时得到了。当使用“go test -race”运行时,我没有感到恐慌,但测试后来失败了。在这两种情况下,尽管有 wg.Wait(),但 goroutine 并未完成执行。

我做了以下更改,现在测试按预期工作:

    expected := 10
    var wg sync.WaitGroup
    wg.Add(expected)
    for i := 0; i < expected; i++ {
        go func(wg *sync.WaitGroup) {
            defer wg.Done()
            // do something
        }(&wg)
    }
    wg.Wait()
Run Code Online (Sandbox Code Playgroud)

我的疑问是:

  1. 到目前为止我看到的很多代码都是wg.Add(1)在 goroutine 内部完成的。为什么在这种特定情况下它会表现出意外?这里发生的情况似乎是,一些 …

synchronization go race-condition goroutine waitgroup

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

mongodb客户端驱动并发安全吗?

在以下代码库中的代码中,创建了 mongodb 客户端(如下所示):

import (
    "context"
    "time"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "go.mongodb.org/mongo-driver/mongo/readpref"
)

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
Run Code Online (Sandbox Code Playgroud)

在我们的场景中:

Goroutine 1 用于collection1读写操作:

  collection1 := client.Database("testing").Collection("collectionone")
Run Code Online (Sandbox Code Playgroud)

Go-routine 2 同时使用collection1&collection2进行读写操作:

 collection2 := client.Database("testing").Collection("collectiontwo")
Run Code Online (Sandbox Code Playgroud)

client在多个 go 例程中使用并发安全吗?

database go mongodb goroutine mongo-go

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

使用goroutine迭代会产生意想不到的结果

我在做一些条件基础上,iteratating变量够程内检查i,发现它是给我结果我没想到,我决定用一些简单的代码来确认.

    for i := 1; i <= 5; i++ {
    wg.Add(1)
    fmt.Println(i)

    go func() {
        fmt.Println(i)
        wg.Done()
    }()


}
wg.Wait()

1
2
3
4
5
6
6
6
6
6
Run Code Online (Sandbox Code Playgroud)

这是预期的行为吗?有人可以解释为什么6被打印5次,虽然我只迭代到5?

concurrency loops go goroutine

0
推荐指数
1
解决办法
102
查看次数

修改goroutine中的结构?

我正在尝试使用goroutine,似乎我无法在goroutine中修改结构的值(下面的示例).这有什么工作吗?

编辑:如果我放置一个睡眠语句,似乎代码运行,表明如果给定更多时间,goroutines将运行,但它们在main()中的所有内容都已执行后完成运行.在继续之前,我如何"等待"我的goroutines完成?

package main

import (
    "fmt"
)

type num struct {
    val int
}

func (d *num) cube_val() {
    fmt.Println("changing value...")
    d.val = d.val*d.val*d.val 
}

func main() {
    a := []num{num{1},num{3},num{2},num{5},num{4}}
    for i := range a {
        go a[i].cube_val()
    }
    // code that waits for go routines to finish should get inserted here ...
    fmt.Println(a) // change does NOT happen

    for i := range a {
        a[i].cube_val()
    }
    fmt.Println(a) // change happens, and fmt.Println statements worked?
}
Run Code Online (Sandbox Code Playgroud)

concurrency struct go goroutine

0
推荐指数
1
解决办法
583
查看次数

为什么这个Go程序这么慢?

我刚刚阅读了Go的一些简短教程,并编写了一个简单的程序筛。Sieve使用sieve算法来打印所有小于10000的质数,这会创建许多go例程。我得到了正确的结果,但是程序非常慢(在我的计算机上为5秒)。我还编写了实现相同算法的lua脚本和python脚本,并且运行速度更快(两者在我的计算机上均为1秒左右)。

请注意,这样做的目的是要了解go例程与其他语言(例如lua)中的协程相比的性能。该实现效率很低,一些评论指出,这不是实现Eratosthenes筛网的正确方法。是的,这是故意的。其他一些答复指出,速度慢是由打印I / O引起的。所以我注释了打印行。

我的问题是为什么我在Go中实现的筛分程序这么慢?这是代码:

package main

import (
  "fmt"
  "sync"
)


type Sieve struct {
  id int;
  msg_queue chan int;
  wg *sync.WaitGroup;
}


func NewSieve(id int) *Sieve {
  sieve := new(Sieve)
  sieve.id = id
  sieve.msg_queue = make(chan int)
  sieve.wg = new(sync.WaitGroup)
  sieve.wg.Add(1)
  return sieve
}


func (sieve *Sieve) run() {
  defer sieve.wg.Done()

  myprime := <-sieve.msg_queue
  if myprime == 0 {
    return
  }
  // fmt.Printf("Sieve (%d) is for prime number %d.\n", sieve.id, myprime)

  next_sieve := NewSieve(sieve.id + 1)
  go next_sieve.run() …
Run Code Online (Sandbox Code Playgroud)

lua go goroutine

0
推荐指数
1
解决办法
169
查看次数