让我举一个例子:
func WaitForStringOrTimeout() (string, error) {
my_channel := make(chan string)
go WaitForString(my_channel)
select {
case found_string := <-my_channel:
return found_string, nil
case <-time.After(15 * time.Minute):
return nil, errors.New("Timed out waiting for string")
}
}
Run Code Online (Sandbox Code Playgroud)
在这个简单的例子中,我有一些函数WaitForString,它会阻塞一段时间并最终返回一个字符串.我想用这个代码包装WaitForString,该代码返回相同的字符串或超时并带有错误.
如果快速找到一个字符串,是否还有一个goroutine在某处运行15分钟的睡眠声明,或者这个垃圾是以某种方式收集的?
如果发生超时并且从未找到字符串,那么仍然存在运行WaitForString的goroutine,即使没有其他例程可以观察它的输出吗?如果WaitForString分配了大量内存但从不返回怎么办?
有没有什么方法可以让WaitForString()意识到超时发生并放弃?
据说如果配置erlang并设置了cookie,那么erlang的进程可以在不同的机器上运行,这对调用者来说是透明的.这样的goroutine可能会运行吗?
我在第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) 我在对象中定义了一个变量(r.something)
func (r *Runner) init() {
r.something = make(map[string]int)
r.something["a"]=1
go r.goroutine()
}
Run Code Online (Sandbox Code Playgroud)
而r.goroutine使用存储在r.something中的值而没有同步.除了r.goroutine()之外,没有其他人会读/写这个值
没有同步可以安全吗?
换句话说:我想在 goroutine start 之前重新使用从其他地方初始化的goroutine中的一些变量.这样安全吗?
附加问题:在r.goroutine()完成之后,我希望能够使用来自其他地方的r.something(没有与其他goroutine的读/写重叠).它也安全吗?
我是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 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数量的信息。
我想在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)
但是当我试图击中端点时,它只是卡住而没有响应.有人使用流功能,以便他/她可以指出我可能正在做的错误.谢谢!
我最近正在探索Go,goroutines如何工作使我感到困惑。
我尝试使用goroutines将之前编写的代码移植到Go中,但出现fatal error: all goroutines are asleep - deadlock!错误。
我正在尝试使用goroutines处理列表中的项目,然后将处理后的值收集到新列表中。但是我在“聚会”部分遇到了问题。
码:
sampleChan := make(chan sample)
var wg sync.WaitGroup
// Read from contents list
for i, line := range contents {
wg.Add(1)
// Process each item with a goroutine and send output to sampleChan
go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg)
}
wg.Wait()
// Read from sampleChan and put into a slice
var sampleList []sample
for s := range sampleChan {
sampleList = append(sampleList, s)
}
close(sampleChan)
Run Code Online (Sandbox Code Playgroud)
从goroutine收集结果的正确方法是什么?
我知道切片不是线程安全的,所以我不能让每个goroutine仅追加到切片中。
func First(query string, replicas ...Search) Result {
c := make(chan Result)
searchReplica := func(i int) {
c <- replicas[i](query)
}
for i := range replicas {
go searchReplica(i)
}
return <-c
}
Run Code Online (Sandbox Code Playgroud)
这个函数来自Rob Pike在2012年的并发模式上的幻灯片.我认为这个函数存在资源泄漏.当第一个发送和接收对发生在通道c上后,函数返回,其他的例程尝试在通道c上发送.所以这里有资源泄漏.谁知道golang好可以证实这一点?如何使用什么样的golang工具检测这种泄漏?
我正在编写一个简单的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)