我是 Golang 的新手,我刚刚通过以下示例了解了 Goroutine 的概念:
package main
import "fmt"
func f(from string) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
}
}
func main() {
f("direct")
go f("goroutine")
go f("goroutine2")
go func(msg string) {
fmt.Println(msg)
}("going")
var input string
fmt.Scanln(&input)
fmt.Println("done")
}
Run Code Online (Sandbox Code Playgroud)
这是执行结果之一:
direct : 0
direct : 1
direct : 2
goroutine : 0
goroutine2 : 0
goroutine2 : 1
goroutine2 : 2
goroutine : 1
goroutine : 2
going
done
Run Code Online (Sandbox Code Playgroud)
我可以看到,goroutine并 …
每当来自客户端的 Web 请求传入时,它都会生成一个 goroutine 来处理每个请求。如果客户端恰好与连接断开连接,Web 服务器是否有可能关闭该特定 goroutine,或者该 goroutine 在执行完所有代码后是否会发现客户端已经断开连接?
有没有办法找出正在运行的函数是否被调用为 goroutine ?
我已经阅读了“go tour”并且我对用 golang 构建一个 websocket 服务器很感兴趣,所以我找到了这个教程https://tutorialedge.net/golang/go-websocket-tutorial/
现在我想知道教程中的 wsEndpoint 函数是否被调用为 goroutine(例如 go wsEndpoint(...))。
我试图阅读 http 包文档,但没有得到清晰的图片,只是猜测处理程序将被 goroutine 调用。真的吗?
我想每 5 分钟运行一次任务来更新我网站上的统计信息,而不会阻止 HTTP 服务器。
我刚刚添加了基本的 HTTP 服务器逻辑和一个工作程序示例。如果我添加了多个这样的任务,这被认为是不好的做法还是有更好的方法?
package main
import (
"fmt"
"net/http"
"time"
)
func Home(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Home page")
}
func schedule(f func(), interval time.Duration) *time.Ticker {
ticker := time.NewTicker(interval)
go func() {
for range ticker.C {
f()
}
}()
return ticker
}
func longRunningTask() {
fmt.Println("Long running task")
}
func main() {
schedule(longRunningTask, time.Second*5)
http.HandleFunc("/", Home)
http.ListenAndServe("127.0.0.1:8080", nil)
}
Run Code Online (Sandbox Code Playgroud) 我今天一直在玩 Goroutines、Channels 和 WaitGroup,在阅读了一段时间之后,我终于开始理解这个概念。
我的问题是我不确定在这样工作时如何处理错误,主要是因为我使用了 WaitGroup。使用 WaitGroup 时,我首先添加将要执行的 goroutine 的数量,但是如果在其中一个过程中发生错误怎么办?
package main
import (
"errors"
"sync"
)
var waitGroup sync.WaitGroup
func main() {
c := make(chan int, 10)
waitGroup.Add(10)
go doSomething(c)
waitGroup.Wait()
}
func doSomething(c chan int) {
for i := 0; i < 10; i++ {
n, err := someFunctionThatCanError()
if err != nil {
// How do I end the routines and WaitGroups here?
}
c <- n
waitGroup.Done()
}
close(c)
}
func someFunctionThatCanError() (int, error) {
return …Run Code Online (Sandbox Code Playgroud) 我对 golang 还很陌生,在其中一个处理函数中,我使用来自不同 goroutine 的通道收集数据,现在想将结果数组作为响应对象返回
所以我给出了一个返回类型作为结构细节,但它抛出了一个错误
如果这不是将 struct 切片作为响应返回的方法,那么我如何将我的结果数组作为响应返回来发布我的请求
错误:
cannot use homePage (type func(http.ResponseWriter, *http.Request) []details) as type func(http.ResponseWriter, *http.Request) in argument to http.HandleFunc
Run Code Online (Sandbox Code Playgroud)
处理函数:
func homePage(w http.ResponseWriter, r *http.Request) []details{
var wg sync.WaitGroup
for _, url := range urls {
out, err := json.Marshal(url)
if err != nil {
panic (err)
}
wg.Add(1)
go do_calc(ch,client,string(out),&wg)
}
fmt.Println("Returning Response")
go func() {
for v := range ch {
results = append(results, v)
}
}()
wg.Wait()
close(ch)
return results
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试暂停和恢复 groutine。我知道我可以sleep跑步,但我正在寻找就像一个按钮“暂停/恢复”而不是一个计时器。
这是我的尝试。我正在使用通道的阻塞功能来暂停,并select根据通道值切换要执行的内容。但是,输出总是Running在我的情况下。
func main() {
ctx := wctx{}
go func(ctx wctx) {
for {
time.Sleep(1 * time.Second)
select {
case <-ctx.pause:
fmt.Print("Paused")
<-ctx.pause
case <-ctx.resume:
fmt.Print("Resumed")
default:
fmt.Print("Running \n")
}
}
}(ctx)
ctx.pause <- struct{}{}
ctx.resume <- struct{}{}
}
type wctx struct {
pause chan struct{}
resume chan struct{}
}
Run Code Online (Sandbox Code Playgroud) 在下面的代码中:
package main
import "fmt"
func main() {
for i := 0; i <= 9; i++ {
go func() {
fmt.Println(i)
}()
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
code$
code$ go install github.com/myhub/cs61a
code$ bin/cs61a
code$
Run Code Online (Sandbox Code Playgroud)
以上程序不提供任何输出。
1)他们是否i在 10 个 go-routines 之间进行单一内存位置的数据竞争?
2)为什么上面的代码不打印自由变量的值i?
在我的程序中,我有几个 go-routines,它们本质上是在运行无休止的进程。为什么?你可能会问,长话短说这是我整个申请的目的,所以改变它是不可能的。我想让用户能够停止单个 go-routine。我知道我可以使用 channel 来通知 go-routines 停止,但是在某些情况下,我可能有 10 个 go-routines 正在运行而我只想停止 1。问题是 go-routines 的数量我想运行的是动态的并基于用户输入。对我来说,添加动态停止 go-routine 并允许单打停止而没有其他功能的最佳方法是什么?
var wg sync.WaitGroup
var v int32 = 0
for i = 0; i < 100; i++{
go func(){
wg.Add(1) // wrong place
atomic.AddInt32(&v,1)
wg.Done()
}
}
wg.Wait()
fmt.Println(v)
Run Code Online (Sandbox Code Playgroud)
这是我从这个视频中看到的一段代码https://subscription.packtpub.com/video/application_development/9781788994880/97598/97608/goroutines
但v总是小于100,我认为原因可能是wg.Wait()因为我们放入wg.Add(1)匿名函数并且在同一个 goroutinewg.Done()中将被立即调用,因此 main goroutine 从阻塞状态恢复执行。
但是如果我们将wg.Add(1)放入 for 循环中, v 将始终为100。
var wg sync.WaitGroup
var v int32 = 0
for i = 0; i < 100; i++{
wg.Add(1)
go func(){
atomic.AddInt32(&v,1)
wg.Done()
}
}
wg.Wait()
fmt.Println(v)
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么我们可以保证 …