标签: goroutine

goroutines是如何工作的,当主要过程结束时它们会死吗?

我编写了一个简单的小例子,将1000万条记录插入mongodb.我开始按顺序工作.然后我查找了如何进行并发,并找到了goroutines.这看起来像我想要的,但它并不像我期望的那样表现.我实现了一个WaitGroup来阻止程序在所有goroutine完成之前退出,但我仍然遇到问题.

所以我将从正在发生的事情开始然后显示代码.当我运行没有goroutine的代码时,所有1000万条记录都插入mongodb罚款.然而,当我添加goroutine时,一些不确定的数量被输入..一般在8500左右给予或采取几百.我检查了mongodb日志,看它是否有问题,没有任何显示.所以我不确定是什么,可能是,只是没有被记录.无论如何,这是代码:

(旁注:我一次只做1条记录,但我把它拆分成一种方法,所以我可以在将来一次测试多条记录......只是还没弄明白如何用mongodb做到这一点然而.)

package main

import (
  "fmt"
  "labix.org/v2/mgo"
  "strconv"
  "time"
  "sync"
)

// structs
type Reading struct {
  Id   string
  Name string
}

var waitGroup sync.WaitGroup

// methods
func main() {
  // Setup timer
  startTime := time.Now()

  // Setup collection
  collection := getCollection("test", "readings")
  fmt.Println("collection complete: " + strconv.FormatFloat(time.Since(startTime).Seconds(), 'f', 2, 64))

  // Setup readings
  readings := prepareReadings()
  fmt.Println("readings prepared: " + strconv.FormatFloat(time.Since(startTime).Seconds(), 'f', 2, 64))

  // Insert readings
  for i := 1; i <= 1000000; i++ {
    waitGroup.Add(1) …
Run Code Online (Sandbox Code Playgroud)

go goroutine

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

如何从通道获取值而无需等待它

在Go中,如果我尝试从通道接收,程序的执行将被停止,直到某个值在通道中.但是,我想要做的是让程序继续执行,如果通道中有值,则对其执行操作.

我想到的伪代码是这样的:

mychan := make(chan int, 1)

go someGoRoutine(mychan) // This might put some value in mychan at some point

for {
    if something in "mychan" {
        // Remove the element from "mychan" and process it
    } else {
        // Other code
    }
}
Run Code Online (Sandbox Code Playgroud)

据我所知,我不能简单地使用,v <- mychan因为这将阻止程序执行,直到值可用.在Go中这样做的方法是什么?

multithreading synchronization asynchronous go goroutine

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

为什么睡眠似乎不适用于goroutine

package main

import (
    "fmt"
    "time"
)

func main() {
    c := make(chan struct{})
    count := 1
    go func() {
        for {
            fmt.Println("foo", count)
            count++
            time.Sleep(2)
        }
        c <- struct{}{}
    }()
    fmt.Println("Hello World!")
    <-c
}
Run Code Online (Sandbox Code Playgroud)

这是我的代码,我发现它没有在每个循环中睡2,并且很快打印出来.这是什么原因?我搜索的是睡眠会让goroutine放弃对cpu的控制,当它再次获得控制权时它会检查自己是在睡觉吗?

time sleep go goroutine

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

没有看到goroutines预期的副作用

我正试图抓住goroutines.拿这个代码:

package main
import "fmt"

var (
    b1 []float64
    b2 []float64
)

func main() {
    go fill(&b1, 10)
    go fill(&b2, 10)

    fmt.Println(b1,b2)

    var s string
    fmt.Scanln(&s)
}

func fill(a *[]float64, n int) {
    for i:=0; i<n; i++ {
        *a = append(*a, rand.Float64()*100)
    }
}
Run Code Online (Sandbox Code Playgroud)

如你所见,我正试图填补两片.但是当以这种方式运行时(带go fill()),它会打印两个空切片.为什么这不起作用?

concurrency append go slice goroutine

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

为什么不推出我的goroutines?

不,这不是因为我的程序结束太快了.

我有这个脚本:

package main

import ("log"; "io/ioutil"; "strings")

const BASE_FILE_NAME = "abc_"

func mygoroutine(file_name string) {
    log.Println("In goroutine for file", file_name)
}


func get_file_names() []string {
  file_names := make([]string, 0)
  files, _ := ioutil.ReadDir("./")
  for _, file := range files {
      if strings.HasPrefix(file.Name(), BASE_FILE_NAME) {
        file_names = append(file_names, file.Name())
      }
  }

  return file_names
}

func main()  {
    file_names := get_file_names()
    for _, file_name := range file_names {
        log.Println("Now lunching goroutine for file", file_name)
        go mygoroutine(file_name)
    }

    log.Println("Finished launching.")

    for {} …
Run Code Online (Sandbox Code Playgroud)

go goroutine

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

代码不是从go块调用的,但是它可以在REPL中运行

我有更新DOM的代码.new-recipe!调用API来获取新的配方字符串.update-recipe-state接下来在屏幕中更新此状态.最后我们打电话给update-transition-buttons.

(defn- add-listener-to-recipe-button! []
  "Listens to go button, creates a new recipe and displays it"
  (create-click-event-listener! (dommy/sel1 :#button-start)
                                #(go (new-recipe!)
                                     (<! (timeout 2000))
                                     (update-recipe-state!)
                                     (<! (timeout 2000))
                                     (update-transition-buttons! "onboarding"))))

;; define your app data so that it doesn't get over-written on reload
(defonce world
  (add-listener-to-recipe-button!))
Run Code Online (Sandbox Code Playgroud)

update-transition-buttons有步骤(利用超时代码之间的一些延迟在这里),如下所示:

(defn- update-transition-buttons! [recipe-name]
  "Updates the buttons with the transition names"
  (go
    ;; Split response in list of actions by splitting on the comma
    (let …
Run Code Online (Sandbox Code Playgroud)

clojure goroutine clojurescript core.async figwheel

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

去例程从URL下载到文件

我当前正在学习GO.在学习了一些基础知识后,我一直在尝试编写一个小程序,它使用goroutine同时将网页(切片中的网址)下载到不同的文件中.这是我写的一些代码:

func downloadFromUrl(url string) {
    tokens := strings.Split(url, "/")
    fileName := tokens[len(tokens)-1]
    // I took out the bit that download the file for testing.
    fmt.Println("Downloading", url, "to", fileName)

}
Run Code Online (Sandbox Code Playgroud)

我评论了实际下载页面以进行测试的位.在我的主要功能中,我这样做:

func main() {
    urls := []string{"http://www.google.com", "http://www.yahoo.com", "http://www.google.com"}

    for _, url := range urls {
        fmt.Println(url);
        go downloadFromUrl(url);
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,当我使用表达式go downloadFromUrl(url);函数downloadFromUrl不运行时.但如果我只是downloadFromUrl(url)在循环中使用它工作正常.我究竟做错了什么?我是否必须在惯例中使用频道?

go goroutine

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

Golang中的游戏循环模拟

我想在go(lang)中创建游戏循环,所以我尝试了这个:

package main

import (
    "fmt"
    // "runtime"
    "sync"
    "time"
)

var v = 0
var wg sync.WaitGroup
var sec = 5

func main() {
    wg.Add(1)
    gameLoop()
    wg.Wait()
}

func gameLoop() {
    time.AfterFunc(16*time.Millisecond, gameLoop)
    v++
    fmt.Println(v)
    if v == sec*60 {
        // fmt.Println("Goroutines: ", runtime.NumGoroutine())
        panic("err")
        wg.Done()
    }
}
Run Code Online (Sandbox Code Playgroud)

该程序以62.5Hz运行(16*time.Millisecond),var sec用于wg.Done()在5秒后调用并导致var v打印300次.

调用这样panic("err")的结果:

panic: err

goroutine 314 [running]:
panic(0x493c60, 0xc420094370)
    /usr/local/go/src/runtime/panic.go:500 +0x1a1
main.gameLoop()
    /home/billyzaelani/Desktop/main.go:26 +0x11f
created by time.goFunc
    /usr/local/go/src/time/sleep.go:154 +0x44
exit status …
Run Code Online (Sandbox Code Playgroud)

go game-loop goroutine

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

ioutil.ReadAll导致goroutine泄漏

为什么我在终止之前有多个goroutine,即使我关闭了resp.body,而我只使用了阻止调用?如果我不消耗resp.Body它只用一个goroutine终止.

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "runtime"
    "time"
)

func fetch() {
    client := http.Client{Timeout: time.Second * 10}
    url := "http://example.com"
    req, err := http.NewRequest("POST", url, nil)
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    _, err = ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
}

func main() {
    fmt.Println("#Goroutines:", runtime.NumGoroutine())
    fetch()
    // runtime.GC()
    time.Sleep(time.Second * 5)
    fmt.Println("#Goroutines:", runtime.NumGoroutine())
}
Run Code Online (Sandbox Code Playgroud)

输出:

#Goroutines: 1
#Goroutines: 3
Run Code Online (Sandbox Code Playgroud)

go goroutine

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

GO例程中缓冲通道范围的输出损坏

为什么像以下这样的GO例程在使用缓冲通道时以随机顺序输出字节序列?

下面是复制错误行为的代码,其中data.csv包含1000行随机数据(大约每行100个字节)加上标题行(总共1001行)的简单CSV.

package main

import (
    "bufio"
    "os"
    "time"
)

func main() {

    var channelLength = 10000
    var channel = make(chan []byte, channelLength)

    go func() {
        for c := range channel {
            println(string(c))
        }
    }()

    file, _ := os.Open("./data.csv")
    scanner := bufio.NewScanner(file)

    for scanner.Scan() {
        channel <- scanner.Bytes()
    }

    <-time.After(time.Second * time.Duration(3600))

}
Run Code Online (Sandbox Code Playgroud)

以下是输出的前6行作为我对"断开输出"的意思的一个例子:

979,C
tharine,Vero,cveror6@blinklist.com,Female,133.153.12.53
980,Mauriz
a,Ilett,milettr7@theguardian.com,Female,226.123.252.118
981
Sher,De Laci,sdelacir8@nps.gov,Female,137.207.30.217
[...]
Run Code Online (Sandbox Code Playgroud)

另一方面,如果channelLength = 0,则代码运行平稳,因此使用无缓冲通道(前6行):

id,first_name,last_name,email,gender,ip_address
1,Hebert,Edgecumbe,hedgecumbe0@apple.com,Male,108.84.217.38
2,Minor,Lakes,mlakes1@marriott.com,Male,231.185.189.39
3,Faye,Spurdens,fspurdens2@oakley.com,Female,80.173.161.81
4,Kris,Proppers,kproppers3@gmpg.org,Male,10.80.182.51
5,Bronnie,Branchet,bbranchet4@squarespace.com,Male,118.117.0.5
[...]
Run Code Online (Sandbox Code Playgroud)

数据是随机生成的.

channel go goroutine

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