我是Go的新手,在理解并发和通道方面遇到了问题.
package main
import "fmt"
func display(msg string, c chan bool){
fmt.Println("display first message:", msg)
c <- true
}
func sum(c chan bool){
sum := 0
for i:=0; i < 10000000000; i++ {
sum++
}
fmt.Println(sum)
c <- true
}
func main(){
c := make(chan bool)
go display("hello", c)
go sum(c)
<-c
}
Run Code Online (Sandbox Code Playgroud)
该计划的输出是:
display first message: hello
10000000000
Run Code Online (Sandbox Code Playgroud)
但我认为它应该只有一行:
display first message: hello
Run Code Online (Sandbox Code Playgroud)
所以在main函数中,<-c阻塞它并等待另外两个rountines将数据发送到通道.一旦主函数从c接收数据,它就应该继续并退出.
显示和总和同时运行,总和需要更长时间,因此显示应该发送真实到c并且程序应该在总结完成之前退出...
我不确定我是否理解清楚.有人可以帮我吗?谢谢!
我正在尝试为大量文件构建一个解析器,我找不到关于我称之为"嵌套goroutines"的资源(也许这不是正确的名字?).
给定了很多文件,每个文件都有很多行.我应该这样做:
for file in folder:
go do1
def do1:
for line in file:
go do2
def do2:
do_something
Run Code Online (Sandbox Code Playgroud)
或者我应该只使用"一级"goroutines,并执行以下操作:
for file in folder:
for line in file:
go do_something
Run Code Online (Sandbox Code Playgroud)
我的问题主要针对性能问题.
谢谢你达到那句话!
我的问题很简单.
我应该将GoRoutines用于一个非常简单的REST API吗?
我基本上只对数据库执行简单查询,验证会话或执行登录.这些操作是否值得设置GoRoutine?GoRoutines何时有用,我该如何设置它们?
正如我们在go中所知,当goroutine必须执行阻塞调用(例如系统调用)或通过cgo调用C库时,可能会创建一个线程.一些测试代码:
package main
import (
"io/ioutil"
"os"
"runtime"
"strconv"
)
func main() {
runtime.GOMAXPROCS(2)
data, err := ioutil.ReadFile("./55555.log")
if err != nil {
println(err)
return
}
for i := 0; i < 200; i++ {
go func(n int) {
for {
err := ioutil.WriteFile("testxxx"+strconv.Itoa(n), []byte(data), os.ModePerm)
if err != nil {
println(err)
break
}
}
}(i)
}
select {}
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,它没有创建很多线程.
? =99=[root /root]$ cat /proc/9616/status | grep -i thread
Threads: 5
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
以下代码运行完全正常:
package main
import (
"fmt"
)
func my_func(c chan int){
fmt.Println(<-c)
}
func main(){
c := make(chan int)
go my_func(c)
c<-3
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我改变
c<-3
Run Code Online (Sandbox Code Playgroud)
至
time.Sleep(time.Second)
c<-3
Run Code Online (Sandbox Code Playgroud)
我的代码没有执行.
我的直觉是main在my_func完成执行之前以某种方式返回,但似乎添加暂停应该没有任何效果.我完全迷失在这个简单的例子上,这里发生了什么?
如果通过Go中的通道发送大型结构,它是否真的在goroutines之间复制?
例如,在下面的代码中,Go实际上会复制goroutines生产者和消费者之间的所有largeStruct数据吗?
package main
import (
"fmt"
"sync"
)
type largeStruct struct {
buf [10000]int
}
func main() {
ch := make(chan largeStruct)
wg := &sync.WaitGroup{}
wg.Add(2)
go consumer(wg, ch)
go producer(wg, ch)
wg.Wait()
}
func producer(wg *sync.WaitGroup, output chan<- largeStruct) {
defer wg.Done()
for i := 0; i < 5; i++ {
fmt.Printf("producer: %d\n", i)
output <- largeStruct{}
}
close(output)
}
func consumer(wg *sync.WaitGroup, input <-chan largeStruct) {
defer wg.Done()
i := 0
LOOP:
for {
select {
case …Run Code Online (Sandbox Code Playgroud) Go运行时(调度程序,垃圾收集器等)可以使用多少个线程?例如,如果GOMAXPROCS是10,那么运行时将使用多少个内核线程?
我读的理由改变GOMAXPROCS对runtime.NumCPU()围棋1.5.有一句话声称"单个goroutine程序的性能可以通过提高GOMAXPROCS运行时的并行性来提高,特别是垃圾收集器."
我真正的问题是:如果我在具有CPU配额的Docker容器中运行单goroutine程序,那么为了获得最大性能,我需要的逻辑处理器的最小数量是多少.
我有一个简单的并发用例,它让我疯狂,我无法找到一个优雅的解决方案.任何帮助,将不胜感激.
我想编写一种方法fetchAll,从远程服务器并行查询未指定数量的资源.如果任何提取失败,我想立即返回第一个错误.
我最初的,天真的实现,泄漏了goroutines:
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
func fetchAll() error {
wg := sync.WaitGroup{}
errs := make(chan error)
leaks := make(map[int]struct{})
defer fmt.Println("these goroutines leaked:", leaks)
// run all the http requests in parallel
for i := 0; i < 4; i++ {
leaks[i] = struct{}{}
wg.Add(1)
go func(i int) {
defer wg.Done()
defer delete(leaks, i)
// pretend this does an http request and returns an error
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
errs <- fmt.Errorf("goroutine …Run Code Online (Sandbox Code Playgroud) 我正在用goroutines做一些测试,只是为了了解它们是如何工作的,但它们似乎根本没有运行.我做了一个非常简单的测试:
package main
import (
"fmt"
)
func test() {
fmt.Println("test")
}
func main() {
go test()
}
Run Code Online (Sandbox Code Playgroud)
我希望这打印"测试",但它根本不做任何事情,没有消息,但也没有错误.我也尝试for {}在程序结束时添加一个,以便给goroutine时间打印一些东西,但这没有帮助.
知道可能是什么问题吗?