我有以下代码,我试图在其中调用 api 10000 次,但出现错误:
package main
import (
"fmt"
"net/http"
"runtime"
"sync"
"time"
)
func main() {
nCPU := runtime.NumCPU()
runtime.GOMAXPROCS(nCPU)
var wg sync.WaitGroup
totalRequests := 100000
wg.Add(totalRequests)
fmt.Println("Starting Go Routines")
start := time.Now()
total := 0
for i := 0; i < totalRequests; i++ {
go func(current int) {
defer wg.Done()
startFunc := time.Now()
_, err := http.Get("http://127.0.0.1:8080/event/list")
// resp, err := http.Get("https://graph.facebook.com/v2.4/me" + "?fields=id%2Cname&access_token=" + "CAACEdEose0cBAEpQvcsvVMQu5oZCyyDjcEPQi9yCdiXimm4F0AYexGHPZAJHgpyrFOJN5X1VMcicNJjlkaCquUqHMZAfRrtxx6K9cRIROrA0OmbqAqCcg8ZA3qJZCHCl68I1n4LtFb5qxPcotlP5ne5PBakK0OUa7sc6FAOWwByOnFtNZBpIe8XDeM4YFa33sDfftVUpZCoBgZDZD")
if err != nil {
fmt.Println(err)
}
// defer resp.Body.Close()
elapsedFunc := …Run Code Online (Sandbox Code Playgroud) 下面是一个例子:
func main() {
c := make(chan int)
i := 0
go goroutine(c)
c <- i
time.Sleep(10 * time.Second)
}
func goroutine(c chan int) {
for {
num := <- c
fmt.Println(num)
num++
time.Sleep(1 * time.Second)
c <- num
}
}
Run Code Online (Sandbox Code Playgroud)
我在 goroutine 中尝试做的是从通道接收数字,打印它,递增并在一秒钟后将其发送回通道。在此之后,我想重复这个动作。
但因此,操作只进行一次。
输出:
0
Run Code Online (Sandbox Code Playgroud)
难道我做错了什么?
当我运行goroutines时,我通常得到40作为值,我知道它的并发性,但为什么最后一个数字来了?我想输出必须是:
Page number: 34
Page number: 12
Page number: 8
Page number: 2
Page number: 29
Run Code Online (Sandbox Code Playgroud)
示例源代码:
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func getWebPageContent(url string, c chan int, val int) interface{} {
if r, err := http.Get(url); err == nil {
defer r.Body.Close()
if body, err := ioutil.ReadAll(r.Body); err == nil {
c <- val
return string(body)
}
} else {
fmt.Println(err)
}
return "XoX"
}
const MAX_TH = 40
func main() {
// pln := …Run Code Online (Sandbox Code Playgroud) 出于某种原因,一旦我开始通过我的goroutine中的通道添加字符串,代码在我运行时就会停止.我认为这是一个范围/闭包问题,所以我将所有代码直接移动到函数中无济于事.我查看了Golang的文档,所有示例都与我的相似,所以我对于出了什么问题毫无头绪.
func getPage(url string, c chan<- string, swg sizedwaitgroup.SizedWaitGroup) {
defer swg.Done()
doc, err := goquery.NewDocument(url)
if err != nil{
fmt.Println(err)
}
nodes := doc.Find(".v-card .info")
for i := range nodes.Nodes {
el := nodes.Eq(i)
var name string
if el.Find("h3.n span").Size() != 0{
name = el.Find("h3.n span").Text()
}else if el.Find("h3.n").Size() != 0{
name = el.Find("h3.n").Text()
}
address := el.Find(".adr").Text()
phoneNumber := el.Find(".phone.primary").Text()
website, _ := el.Find(".track-visit-website").Attr("href")
//c <- map[string] string{"name":name,"address":address,"Phone Number": phoneNumber,"website": website,};
c <- fmt.Sprint("%s%s%s%s",name,address,phoneNumber,website)
fmt.Println([]string{name,address,phoneNumber,website,})
}
}
func …Run Code Online (Sandbox Code Playgroud) 我有两个go例程函数,一个创建数据,一个将数据添加到数据库.当我完成创建数据时,我想完成添加数据,但我不知道有多少次我要调用该函数.
for {
select {
case c <- dataChan:
go func() {
if data == false {
return // keeps the program running but never exits
}
createData(c.Data) // sends data to dataChan until data == false
}
go func() {
addData(c.Data) // need to keep the program running until all these goroutines finish
}
}
}
Run Code Online (Sandbox Code Playgroud)
createData()创建并发送数据到dataChan基于一些变量它最终会设置data到false通过返回一遍又一遍,并导致程序举行公开和停止创造更多的数据,但我觉得应该有一个更清洁的方式,让我所有addData()goroutines完成后退出.我见过人们为此使用了一个频道,但我不确切地知道我将调用该函数的次数.
更新:工作代码
var wg sync.WaitGroup
for {
select {
case c <- dataChan:
wg.Add(1) …Run Code Online (Sandbox Code Playgroud) 我是Go的新手.在下面的示例中,多个go例程正在从无缓冲的通道中消耗.
代码:
var c = make(chan int)
func f() {
for val := range c {
fmt.Printf("routine 1 : %v\n", val)
}
}
func g() {
fmt.Printf("routine 2 : %v\n", <-c)
}
func main() {
go f()
go g()
c <- 0
c <- 1
c <- 2
c <- 3
c <- 4
c <- 5
close(c)
}
Run Code Online (Sandbox Code Playgroud)
输出是:
routine 1 : 0
routine 1 : 2
routine 2 : 1
routine 1 : 3
routine 1 : 4 …Run Code Online (Sandbox Code Playgroud) 第一次与go,并试图开始惯例和WaitGroups工作.
我有一个包含100行数据的CSV文件.(101包括标题)
我有以下简单的代码:
package main
import (
"bufio"
"fmt"
"io"
"os"
"sync"
"time"
)
func main() {
start := time.Now()
numRows := 0
waitGroup := sync.WaitGroup{}
file, _ := os.Open("./data.csv")
scanner := bufio.NewScanner(file)
scanner.Scan() // to read the header
for scanner.Scan() {
err := scanner.Err()
if err != nil && err != io.EOF {
panic(err)
}
waitGroup.Add(1)
go (func() {
numRows++
waitGroup.Done()
})()
}
waitGroup.Wait()
file.Close()
fmt.Println("Finished parsing ", numRows)
fmt.Println("Elapsed time in seconds: ", time.Now().Sub(start))
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时, …
我正在使用它来接收SNMP陷阱:https://github.com/soniah/gosnmp 现在,让我说我想以编程方式突破(取自此处):
错误:= tl.Listen("0.0.0.0:9162")
我最好的方法是什么?
我对Golang有些新意,并没有找到一种方法来打破我无法修改的goroutine("第三方").
谢谢,
很快就会发现,我是golang n00b。
我有一些基于事件通道启动goroutine的go代码。假设它启动了2个goroutine,因为我们收到了2个START类型的事件。
goroutine以uri作为参数开始,这给了我们一些独特之处。
稍后我们收到一个STOP类型的事件。
如何停止以相同uri开始的goroutine?
for {
select {
case event := <-eventCh:
if event.Entry != nil {
switch event.Action {
case foo.START:
log.Println("uri: ", event.Entry.URI)
go func(c chan []byte, u string) error{
//awesome goroutine code
}(myChan, event.Entry.URI)
case foo.STOP:
log.Println("uri: ", event.Entry.URI)
//I'd like to terminate the goroutine that matches event.Entry.URI
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 我需要从外部服务为我的系统并行获取多个字段(在此示例中,由Name(),Age()和CanDrive()方法模拟)。
fetchUser()方法可以实现我想要的功能,但是如果您认为我可以有10个以上的字段,那么它似乎太冗长了。有没有更好的方法可以实现这一目标?
游乐场:https : //play.golang.org/p/90sNq1GmrD8
代码(与游乐场相同):
package main
import (
"fmt"
"sync"
)
type User struct {
Name string
Age int
CanDrive *bool
}
func Name() (string, error) {
return "foobar", nil
}
func Age() (int, error) {
return 25, nil
}
func CanDrive() (bool, error) {
return true, nil
}
func fetchUser() (*User, error) {
var wg sync.WaitGroup
errs := make(chan error)
user := &User{}
wg.Add(1)
go func() {
var err error
defer wg.Done()
user.Name, err = Name() …Run Code Online (Sandbox Code Playgroud)