假设我想设置一个for循环但不想阻止执行,显然我可以将for循环放在一个函数中f并调用go f并继续我的生活,
但我很好奇是否有办法go for直接调用, 就像是:
fmt.Println("We are doing something")
//line below is my question
go for i := 1; i < 10; i ++ {
fmt.Println("stuff running in background")
}
// life goes on
fmt.Println("c'est la vie")
Run Code Online (Sandbox Code Playgroud) 据说如果配置erlang并设置了cookie,那么erlang的进程可以在不同的机器上运行,这对调用者来说是透明的.这样的goroutine可能会运行吗?
正如我从 golang 文档中了解到的,如果我将 runtime.GOMAXPROCS(8) 设置为 8 核(intel i7)的 cpu,然后启动一个无限循环的 goroutine,其他 gorutines 不应该被阻塞,因为有足够的线程和 goprocs。但是在使用 net/http 包时就不是这样了,一个无限循环的 goroutine 会在几次调用后阻塞 http 服务器。任何人都可以帮助解释原因吗?
服务器代码:
package main
import (
"fmt"
"log"
"net/http"
"runtime"
)
func myHandler(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("hello"))
}
func infiniteloop() {
for {
}
}
func main() {
// set max procs for multi-thread executing
runtime.GOMAXPROCS(runtime.NumCPU())
// print GOMAXPROCS=8 on my computer
fmt.Println("GOMAXPROCS=", runtime.GOMAXPROCS(-1))
http.Handle("/", http.HandlerFunc(myHandler))
// uncomment …Run Code Online (Sandbox Code Playgroud) 我在第30页阅读了Twelve Go Best Practices和遭遇以及有趣的例子.
func sendMsg(msg, addr string) error {
conn, err := net.Dial("tcp", addr)
if err != nil {
return err
}
defer conn.Close()
_, err = fmt.Fprint(conn, msg)
return err
}
func broadcastMsg(msg string, addrs []string) error {
errc := make(chan error)
for _, addr := range addrs {
go func(addr string) {
errc <- sendMsg(msg, addr)
fmt.Println("done")
}(addr)
}
for _ = range addrs {
if err := <-errc; err != nil {
return err …Run Code Online (Sandbox Code Playgroud) 我是Go的新手,试图找出同时从中提取信息的最佳方式REST API.目的是对a进行多个并发调用API,每次调用返回不同类型的数据.
我目前有:
s := NewClient()
c1 := make(chan map[string]Service)
c2 := make(chan map[string]ServicePlan)
c3 := make(chan map[string]ServiceInstance)
c4 := make(chan map[string]ServiceBinding)
c5 := make(chan map[string]Organization)
c6 := make(chan map[string]Space)
go func() {
c1 <- GetServices(s)
}()
go func() {
c2 <- GetServicePlans(s)
}()
go func() {
c3 <- GetServiceInstances(s)
}()
go func() {
c4 <- GetServiceBindings(s)
}()
go func() {
c5 <- GetOrganizations(s)
}()
go func() {
c6 <- GetSpaces(s)
}()
services := <- c1 …Run Code Online (Sandbox Code Playgroud) 从戴夫·切尼博客,下面的代码显然会导致比赛的情况下仅通过改变来解决func (RPC) version() int到func (*RPC) version() int:
package main
import (
"fmt"
"time"
)
type RPC struct {
result int
done chan struct{}
}
func (rpc *RPC) compute() {
time.Sleep(time.Second) // strenuous computation intensifies
rpc.result = 42
close(rpc.done)
}
func (RPC) version() int {
return 1 // never going to need to change this
}
func main() {
rpc := &RPC{done: make(chan struct{})}
go rpc.compute() // kick off computation in the background
version := …Run Code Online (Sandbox Code Playgroud) 对于以下代码:
func main() {
goRtns := runtime.NumGoroutine()
fmt.Println("goroutines:", goRtns)
}
Run Code Online (Sandbox Code Playgroud)
输出为1。但这是在“过程”中,没有goroutines被明确调用:
“在计算中,进程是正在执行的计算机程序的实例。它包含程序代码及其当前活动。根据操作系统(OS),进程可能由多个执行线程组成,这些线程执行指令同时进行。”
同样来自克里希纳·桑达拉姆(Krishna Sundarram)出色的“ goroutines如何工作”博客文章:http : //blog.nindalf.com/how-goroutines-work/
“创建goroutine不需要太多的内存,仅需要2kB的堆栈空间。它们可以通过根据需要分配和释放堆存储来增长。”
那么我的问题是:运行时库将正在运行的代码实例(我简单的main.go函数)计为goroutine。我是否假定父进程被视为go例程,并且具有相同的内存分配,垃圾回收等规则?假设读取有关goroutine执行的事实与运行它的总体go进程类似,是否明智?关于上面关于goroutine的第二个引号,这听起来像是一个程序在执行程序时增大/缩小其堆栈空间的过程,这是编程的标准范例。
go流程和例程是否共享相同的规则?还是我只是缺少有关报告的goroutine数量的信息。
我正在编写一个并行处理矩阵的程序。
我的矩阵是使用常量创建的n。
const n = 10
Run Code Online (Sandbox Code Playgroud)
频道是用以下代码创建的:
a := make(chan [n][n]int)
Run Code Online (Sandbox Code Playgroud)
这适用于任何低于大约值的任何东西12,n但任何更大的东西都会出现以下错误:
channel element type too large (>64kB)
Run Code Online (Sandbox Code Playgroud)
查看教程等,似乎缓冲通道可能是解决此问题的方法,但我尝试使用以下代码执行此操作,并给出了相同的错误:
a := make(chan [n][n]int, 1000)
Run Code Online (Sandbox Code Playgroud)
我是正确使用缓冲通道还是它们不是解决此问题的方法?任何关于我如何推进这一点的提示都非常感谢。
编辑:继给出的答案和评论之后,我现在正在尝试创建一个全局矩阵,该矩阵是空白的并且 go 例程可以写入。
const n int = 1024
blank [n][n]int
Run Code Online (Sandbox Code Playgroud)
我不确定如何在全球范围内声明它,并已尝试通过上述方法解决此问题。是否需要全局初始化?我似乎尝试的一切都会出错。
我想在golang中使用gin-gonic服务器创建一个流API.
func StreamData(c *gin.Context) {
chanStream := make(chan int, 10)
go func() {for i := 0; i < 5; i++ {
chanStream <- i
time.Sleep(time.Second * 1)
}}()
c.Stream(func(w io.Writer) bool {
c.SSEvent("message", <-chanStream)
return true
})
}
router.GET("/stream", controller.StreamData)
Run Code Online (Sandbox Code Playgroud)
但是当我试图击中端点时,它只是卡住而没有响应.有人使用流功能,以便他/她可以指出我可能正在做的错误.谢谢!
我正在编写一个简单的tcp服务器,goroutine模型非常简单:
一个goroutine负责接受新的连接。对于每个新连接,将启动三个goroutine:
目前,一台服务器最多可服务1000个用户,因此我不会尝试限制goroutine的数量。
for {
conn, err := listener.Accept()
// ....
connHandler := connHandler{
conn: conn,
done: make(chan struct{}),
readChan: make(chan string, 100),
writeChan: make(chan string, 100),
}
// ....
go connHandler.readAll()
go connHandler.processAll()
go connHandler.writeAll()
}
Run Code Online (Sandbox Code Playgroud)
我使用done通道通知所有三个通道完成,当用户注销或永久性网络错误发生时,done通道将被关闭(使用sync.Once确保关闭仅发生一次):
func (connHandler *connHandler) Close() {
connHandler.doOnce.Do(func() {
connHandler.isClosed = true
close(connHandler.done)
})
}
Run Code Online (Sandbox Code Playgroud)
下面是writeAll()方法的代码:
func (connHandler *connHandler) writeAll() {
writer := bufio.NewWriter(connHandler.conn)
for {
select {
case <-connHandler.done:
connHandler.conn.Close()
return
case msg := …Run Code Online (Sandbox Code Playgroud)