我是Go的新手,我正在尝试编写一个简单的程序,迭代MongoDB数据库中的所有用户,并且每个用户使用'mgo'包迭代他的所有帖子.
package main
import (
"fmt"
"labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
)
type User struct {
Id string
Email string
}
type Post struct {
Id string
Description string
}
func handleUser(db *mgo.Database, user *User) {
fmt.Println("ID: ", user.Id, " EMAIL: ", user.Email)
result := Post{}
iter := db.C("posts").Find(bson.M{"user_id": user.Id}).Iter()
for iter.Next(&result) {
fmt.Println("POST ID: ", result.Id, " POST DESCRIPTION: ", result.Description)
}
}
func main() {
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
db := session.DB("mydb") …Run Code Online (Sandbox Code Playgroud) 我最近开始使用go,我对这个程序的执行顺序感到很困惑.我希望我不是在这里问一些非常微不足道的问题.
这在golang之旅基本上是#69,我插入了一些Println; 链接到游乐场:http://play.golang.org/p/PXDlD3EA2f
func fibonacci(c, quit chan int) {
x, y := 0, 1
fmt.Println("Inside the fibonacci")
for {
select {
case c <- x:
fmt.Println("Inside the for, first case, before reassigning ", x, y)
x, y = y, x+y
fmt.Println("Inside the for, first case, after reassigning ", x, y)
case <-quit:
fmt.Println("quit")
return
}
}
}
func main() {
fmt.Println("Begin of Main")
c := make(chan int)
quit := make(chan int)
fmt.Println("Before gonig to the func")
go …Run Code Online (Sandbox Code Playgroud) 令我感到惊讶的是,惯例似乎完全交错......看到这个之后,我开始相信有一些关于内部的缺失信息,我还没有学到.例:
$ go run x.go > output
$ grep ping output | wc -l
404778
$ grep pong output | wc -l
404777
$ cat x.go
package main
import (
"fmt"
"time"
)
type Ball struct{ hits int }
func main() {
table := make(chan *Ball)
go player("ping", table)
go player("pong", table)
table <- new(Ball) // game on; toss the ball
time.Sleep(1 * time.Second)
<-table // game over; grab the ball
}
func player(name string, table chan *Ball) {
for …Run Code Online (Sandbox Code Playgroud) 下面是一个启动外部进程的函数,将正则表达式与进程的标准输出进行匹配,并返回匹配的内容.
func (c *Colony) startCircuit(peer *string) (string, error) {
var (
err error
cmd *exec.Cmd
anchorChan chan string
)
// ... (omitted for readability)
// get the anchor from standard output
go func() {
defer out.Close()
anchorChan = make(chan string)
for scanner := bufio.NewScanner(out); scanner.Scan(); {
line := scanner.Text()
if anchor := reRootAnchor.FindString(line); anchor != "" {
log.Println("Started circuit server with anchor:", anchor)
anchorChan <- anchor
break
}
}
}()
anchor := <-anchorChan
return anchor, err
}
Run Code Online (Sandbox Code Playgroud)
运行该函数时,我获得以下输出,表明确实找到了匹配并且(可能)被推入anchorChan: …
出于某种原因,当我删除fmt.Printlns然后代码阻塞.我不知道为什么会这样.我想要做的就是实现一个简单的并发限制器......
我从来没有经历过这么奇怪的事情.这就像fmt冲刷变量或其他东西并使其工作.
此外,当我使用常规函数而不是goroutine时,它也可以工作.
这是以下代码 -
package main
import "fmt"
type ConcurrencyLimit struct {
active int
Limit int
}
func (c *ConcurrencyLimit) Block() {
for {
fmt.Println(c.active, c.Limit)
// If should block
if c.active == c.Limit {
continue
}
c.active++
break
}
}
func (c *ConcurrencyLimit) Decrease() int {
fmt.Println("decrease")
if c.active > 0 {
c.active--
}
return c.active
}
func main() {
c := ConcurrencyLimit{Limit: 1}
c.Block()
go func() {
c.Decrease()
}()
c.Block()
}
Run Code Online (Sandbox Code Playgroud)
澄清:尽管我接受了@kaedys的回答(这里 …
代码很简单如下:
package main
import (
"fmt"
// "sync"
"time"
)
var count = uint64(0)
//var l sync.Mutex
func add() {
for {
// l.Lock()
// fmt.Println("Start ++")
count++
// l.Unlock()
}
}
func main() {
go add()
time.Sleep(1 * time.Second)
fmt.Println("Count =", count)
}
Run Code Online (Sandbox Code Playgroud)
案例:
那么......我在共享变量中的使用有问题......?我的问题:
环境:1.转到版本go1.8 linux/amd64 2. 3.10.0-123.el7.x86_64 3. CentOS Linux版本7.0.1406(核心版)
以下Go代码示例在行c <- byte(0)和之间具有Race条件close(c).运行代码时会发出信号go test -race.
func TestRace(t *testing.T) {
var c = make(chan byte, 20)
go func() {
defer func() {
if r := recover(); r == nil {
t.Error("expected panic error")
}
}()
for i := 0; i < 25; i++ {
c <- byte(0)
}
t.Error("expected a panic")
}()
close(c)
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能避免这种竞争条件?
编辑:根据他的评论中的Icza建议,这是解决方案:
func TestRace(t *testing.T) {
var c = make(chan byte, 20)
var done = make(chan struct{})
go func() { …Run Code Online (Sandbox Code Playgroud) 我有一个函数可能会或可能不会被称为异步go-routine.
func APICall(request *HTTPRequest) *HTTPResponse
Run Code Online (Sandbox Code Playgroud)
*HTTPRequest 是指向结构的指针,该结构包含构建请求所需的各种数据:
type HTTPRequest struct {
// Represents a request to the twitter API
method string
baseurl string
urlParams map[string]string
bodyParams map[string]string
authParams map[string]string
responseChan chan *HTTPResponse
}
Run Code Online (Sandbox Code Playgroud)
如果被称为goroutine,即传入一个频道; 我们构建请求并将响应写入所提供通道的*HTTPResponse对象(也是结构).在没有通道的情况下接受对函数的调用的最优雅/惯用方法是什么(即不是异步)
目前,我们在APICall的主体内做了类似的事情来处理这两种函数调用:
if request.responseChan != nil { // If a response channel has been specified, write to that channel
request.responseChan <- &twitterHTTPResponse{body, nil}
return nil // Not returning a struct
} else {
return &twitterHTTPResponse{body, nil} // Return a pointer to a new struct representing the …Run Code Online (Sandbox Code Playgroud) 有人可以解释一下,为什么goroutine有无限for循环并且循环select内部,循环中的代码只运行一次?
package main
import (
"time"
)
func f1(quit chan bool){
go func() {
for {
println("f1 is working...")
time.Sleep(1 * time.Second)
select{
case <-quit:
println("stopping f1")
break
}
}
}()
}
func main() {
quit := make(chan bool)
f1(quit)
time.Sleep(4 * time.Second)
}
Run Code Online (Sandbox Code Playgroud)
输出:
f1 is working...
Program exited.
Run Code Online (Sandbox Code Playgroud)
但是,如果“选择”被注释掉:
package main
import (
"time"
)
func f1(quit chan bool){
go func() {
for {
println("f1 is working...")
time.Sleep(1 * time.Second)
//select{
//case <-quit:
//println("stopping …Run Code Online (Sandbox Code Playgroud) 是否有类似java Thread.isAlive()的goroutine 函数?
我正在尝试生成一些goroutine,这些线程本来应该是长寿的线程,但是我担心goroutine会在进程中死去,是否可以在我的主线程中执行检查以查看goroutine是否还活着?