- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有this project试图在 Go 中同时运行无限制的大查询。父项目都是 Python。我需要能够跟踪查询结果,就像在 map 中一样。
Input:
{
'reports_portal': 'select * from reports_portal',
'billing_portal': 'select * from billing_portal',
}
output:
{
'reports_portal': [23, 123, 5234, 632],
'billing_portal': [23, 123, 5234, 632],
}
等等
这些大查询需要异步运行,因为它们非常慢(从 UI 的角度来看,SRE 需要等待 15-30 秒才能获得结果。
我首先尝试将项目异步写入 map :
package main
import (
"fmt"
)
func add_to_map(m map[string] string, word string) map[string]string {
added_word := word + " plus more letters"
m[word] = added_word
return m
}
func main() {
words_map := make(map[string]string)
words := []string{"giraffe", "cat", "dog", "turtle"}
for _, this_word := range words {
go add_to_map(words_map, this_word)
}
fmt.Println(words_map)
}
爆炸像:
$ go run try_asynchronous.go
fatal error: concurrent map writes
goroutine 7 [running]:
runtime.throw(0x10b3b96, 0x15)
/usr/local/Cellar/go/1.8.1/libexec/src/runtime/panic.go:596 +0x95 fp=0xc420032eb8 sp=0xc420032e98
runtime.mapassign(0x109ad20, 0xc420016270, 0xc420032fa0, 0x10b3268)
/usr/local/Cellar/go/1.8.1/libexec/src/runtime/hashmap.go:499 +0x667 fp=0xc420032f58 sp=0xc420032eb8
main.add_to_map(0xc420016270, 0x10b1ba0, 0x3, 0x0)
/tmp/golang-w-python/try_asynchronous.go:10 +0xa3 fp=0xc420032fc0 sp=0xc420032f58
runtime.goexit()
/usr/local/Cellar/go/1.8.1/libexec/src/runtime/asm_amd64.s:2197 +0x1 fp=0xc420032fc8 sp=0xc420032fc0
created by main.main
/tmp/golang-w-python/try_asynchronous.go:19 +0xc8
goroutine 1 [runnable]:
fmt.(*pp).fmtString(0xc42001e0c0, 0x10b1f52, 0x7, 0x76)
/usr/local/Cellar/go/1.8.1/libexec/src/fmt/print.go:424 +0x1a2
fmt.(*pp).printValue(0xc42001e0c0, 0x10953c0, 0xc42000e260, 0x98, 0x76, 0x1)
/usr/local/Cellar/go/1.8.1/libexec/src/fmt/print.go:729 +0x27aa
fmt.(*pp).printValue(0xc42001e0c0, 0x109ad20, 0xc420016270, 0x15, 0x76, 0x0)
/usr/local/Cellar/go/1.8.1/libexec/src/fmt/print.go:750 +0x103d
fmt.(*pp).printArg(0xc42001e0c0, 0x109ad20, 0xc420016270, 0x76)
/usr/local/Cellar/go/1.8.1/libexec/src/fmt/print.go:682 +0x217
fmt.(*pp).doPrintln(0xc42001e0c0, 0xc420045f28, 0x1, 0x1)
/usr/local/Cellar/go/1.8.1/libexec/src/fmt/print.go:1138 +0xa1
fmt.Fprintln(0x1108140, 0xc42000c018, 0xc420045f28, 0x1, 0x1, 0xc420045ef0, 0xc420045ee0, 0x1087218)
/usr/local/Cellar/go/1.8.1/libexec/src/fmt/print.go:247 +0x5c
fmt.Println(0xc420045f28, 0x1, 0x1, 0x10b1e6f, 0x6, 0x0)
/usr/local/Cellar/go/1.8.1/libexec/src/fmt/print.go:257 +0x57
main.main()
/tmp/golang-w-python/try_asynchronous.go:21 +0x132
exit status 2
基于需要一次运行多个查询并尝试通过名称跟踪结果,我希望在异步期间写入 map 。但是 fatal error: concurrent map writes
说你不能。
我不明白
编辑:
我所拥有的返回结果的最接近的东西不是异步的:
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
var mutex sync.Mutex
var wg sync.WaitGroup
func random_sleep() {
r := rand.Intn(3000)
time.Sleep(time.Duration(r) * time.Millisecond)
}
func add_to_map(m map[string] string, word string) {
defer wg.Done()
added_word := word + " plus more letters"
mutex.Lock()
defer mutex.Unlock()
fmt.Println("Before sleep")
random_sleep()
m[word] = added_word
fmt.Println("Added word %v", word)
}
func main() {
words_map := make(map[string]string)
words := []string{"giraffe", "cat", "dog", "turtle"}
for _, this_word := range words {
wg.Add(1)
go add_to_map(words_map, this_word)
}
wg.Wait()
fmt.Println(words_map)
}
结果错误:
cchilders:~/work_projects/metricsportal/golang_integration (feature/golang-query)
$ go run try_async.go
Before sleep
Added word %v turtle
Before sleep
Added word %v cat
Before sleep
Added word %v giraffe
Before sleep
Added word %v dog
map[dog:dog plus more letters turtle:turtle plus more letters cat:cat plus more letters giraffe:giraffe plus more letters]
cchilders:~/work_projects/metricsportal/golang_integration (feature/golang-query)
$ go run try_async.go
Before sleep
Added word %v turtle
Before sleep
Added word %v cat
Before sleep
Added word %v giraffe
Before sleep
Added word %v dog
map[dog:dog plus more letters turtle:turtle plus more letters cat:cat plus more letters giraffe:giraffe plus more letters]
结果应该非常快,不超过 3 秒(我认为随机的最大值):
Expectation -
Before sleep
Before sleep
Before sleep
Before sleep
Added word %v cat
Added word %v giraffe
Added word %v turtle
Added word %v dog
最佳答案
好吧,让我澄清一些事情并帮助你。
你不需要从这里返回修改后的 map ,因为你的函数获取对映射的引用而不是它的副本。 (让我们忽略这个事实你完全忽略了返回值)
func add_to_map(m map[string] string, word string) map[string]string {
added_word := word + " plus more letters"
m[word] = added_word
return m
}
接下来您需要同步对 map 的访问。您可以使用 mutex为此。
import "sync"
var mutex sync.Mutex //glabal variable but can be created as local also
func add_to_map(m map[string] string, word string) {
added_word := word + " plus more letters"
// here you can do long to compute task and calculate result
// calc here
mutex.Lock() //result ready lock mutex
defer mutex.Unlock() // unlock mutex when we return from function
m[word] = added_word // result write to shared map
}
请注意,在 Go 1.9 中会有一个 Concurrent Map类型。
编辑:您需要等待所有 go-routines 完成,因为您的 main()
现在先于它们完成。您可以使用 WaitGroup 来完成此操作
package main
import (
"fmt"
"sync"
)
var mutex sync.Mutex
var wg sync.WaitGroup
func add_to_map(m map[string] string, word string) {
defer wg.Done()
added_word := word + " plus more letters"
// do heavy work here
//
mutex.Lock()
defer mutex.Unlock()
m[word] = added_word
}
func main() {
words_map := make(map[string]string)
words := []string{"giraffe", "cat", "dog", "turtle"}
for _, this_word := range words {
wg.Add(1)
go add_to_map(words_map, this_word)
}
wg.Wait()
fmt.Println(words_map)
}
关于python - 运行 Go 异步操作并写入 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45378537/
我正在使用 go 图表库 https://github.com/wcharczuk/go-chart制作条形图。我面临的问题是标签值很长,我想将文本旋转 45 度以显示完整文本 我喜欢显示的日期格式是
我在构建一个非常简单的通过 cgo 调用 c 代码的 go 程序时遇到了问题。我的设置: $: echo $GOPATH /go $: pwd /go/src/main $: ls ctest.c
没有 C 的背景,只有 Go 的“初学者”经验,我正在尝试弄清楚 main.go 是实际需要的还是只是一个约定。 我想创建一个简单的网络 API,但有人可以为我澄清一下吗? 最佳答案 main.go
我read从 Go 1.4 开始,Go 运行时是用 Go 本身编写的(而不是用 C)。 这怎么可能?如果 Go 程序在运行时之上运行,并且运行时是 Go 程序,那么运行时是否在自身之上运行? 最佳答案
这是“Go 之旅”中的代码示例 Range and Close : package main import ( "fmt" ) func fibonacci(n int, c chan int
给定以下 go.mod 文件: module foo go 1.12 require ( github.com/bar/baz v1.0.0 github.com/rat/cat v1
我有一个 CI/CD 管道,它需要跨平台并与几个不同的管理程序一起工作。为了不必更改 Windows 和 Linux 的构建任务,我认为 Go 将是编写一次代码并在任何地方运行的好方法。然而,考虑到
我有一个 Dockerfile,用于使用 go build 编译 Go 应用程序。我进行了研究,确实建议将 go build 用于生产。 但是我找不到正确的答案来解释为什么。 我了解 go run 创
我尝试在命令提示符#Go lang 中运行该程序-但是当我键入运行“go run hello.go”命令时,我开始了 CreateFile hello.go:The system cannot fin
我正在使用“Go 编程语言”一书学习 Go。第一章介绍os.Open用于读取文件的模块。我尝试打开如下所示的 go 文件。 f, err = os.Open("helloworld.go") 我收
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题?通过 editing this post 添加详细信息并澄清问题. 2年前关闭。 Improve this
为了解决我对 goroutine 的一些误解,我去了 Go 操场跑了 this code : package main import ( "fmt" ) func other(done cha
这个问题在这里已经有了答案: Evaluate/Execute Golang code/expressions like js' eval() (5 个回答) 1年前关闭。 对于任何 go 程序,我想
这是我基本上试图从路径打印基准的代码。 这意味着,如果用户输入“/some/random/path.java”,则输出将为“path”。同样,如果用户arg为“/another/myapp.c”,则输
$ go version 1.13.3 我的文件夹结构如下: GOPATH +---src +--- my-api-server +--- my-auth-server
这个问题在这里已经有了答案: How to embed file for later parsing execution use (4 个答案) What's the best way to bun
我觉得这有点奇怪,为什么这段代码不起作用? package main import "fmt" func main() { var i, j int = 1, 2 k
go编译器执行完如下命令后的可执行文件存放在哪里? $> go run file.go 最佳答案 在 /tmp 文件夹中,如果您使用的是 unix 机器。 如果您使用的是 Windows,则在 \Us
我目前正在开始使用 Go,并且已经深入研究了有关包命名和工作区文件夹结构的注意事项。 不过,我不太确定如何根据 Go 范式正确组织我的代码。 这是我当前的结构示例,它位于 $GOPATH/src 中:
假设我有一个接受用户输入的 Lua 程序,而该输入恰好是有效的 Lua 源代码。这是在程序仍在运行时进行清理、编译和执行的。 Go 是否(或将)实现这样的事情? 最佳答案 我认为以下两个项目之间有足够
我是一名优秀的程序员,十分优秀!