Go 中的并行处理
并行编程涉及同时执行多个任务,从而可以提高可分为独立单元的应用程序的性能。 Go 中实现并行性的一种方法是通过 goroutine,即与主程序并发执行的轻量级线程。
考虑以下代码:
<code class="go">package main import ( "fmt" "math/rand" "time" ) func main() { for i := 0; i < 3; i++ { go f(i) } // prevent main from exiting immediately var input string fmt.Scanln(&input) } func f(n int) { for i := 0; i < 10; i++ { dowork(n, i) amt := time.Duration(rand.Intn(250)) time.Sleep(time.Millisecond * amt) } } func dowork(goroutine, loopindex int) { // simulate work time.Sleep(time.Second * time.Duration(5)) fmt.Printf("gr[%d]: i=%d\n", goroutine, loopindex) }</code>
此代码使用 goroutine 并发执行 f函数三次。 dowork 函数通过休眠 5 秒来模拟一些工作。
你能假设 dowork 函数会并行执行吗?
是的,你可以做出这个假设。默认情况下,Go 将 GOMAXPROCS 设置为可用核心数,这允许多个 goroutine 并发执行。
这是实现并行性的正确方法吗?
这是实现并行性的有效方法,但它可能不是最有效的方法。使用没有同步机制的 goroutine 可能会导致数据竞争和不正确的结果。
使用通道和单独的 dowork Workers
实现并行性的一种更加结构化和可扩展的方法是使用渠道和单独的 dowork 工作人员。这种方法确保每个 goroutine 都有自己的共享数据副本,并通过消息传递进行通信。
这是一个使用通道的示例:
<code class="go">var results = make(chan int) // channel to collect results func main() { // spawn a worker for each goroutine for i := 0; i < 3; i++ { go worker(i) } // collect results from the worker goroutines for i := 0; i < 10; i++ { result := <-results fmt.Println("Received result:", result) } } func worker(n int) { for i := 0; i < 10; i++ { // perform work and send result through the channel res := dowork(n, i) results <- res } }</code>
结论
Go 中的并行性可以通过 goroutine 来实现。使用通道和单独的工作人员是一种更加结构化和可扩展的方法,可以确保数据完整性并提高性能。
以上是与单独使用 goroutine 相比,通道和单独的工作线程如何提高 Go 中的并行性?的详细内容。更多信息请关注PHP中文网其他相关文章!