下面我就来详细讲解Go并发编程中使用channel的方法的完整攻略。
什么是channel
Go语言中的channel是一种通信机制,用于协调多个goroutine之间的交互和同步。简单来说,channel就是一个通道,通过它可以在goroutine之间传递数据,实现数据共享,实现同步或异步的通信。
channel的创建和关闭
channel是通过内置函数make创建的,格式为:make(chan <type>)
,其中type指定了channel中传输的数据类型。
channel可以通过内置函数close关闭,格式为:close(channel)
。
channel的使用方法
读写channel
通过channel的读写操作,可以实现goroutine之间的数据传递。
写channel
数据通过<-
运算符写入channel中,格式为:channel <- data
,其中data是要写入channel中的数据。如果channel已经满了,则该操作会被阻塞,直到有其他goroutine从channel中读取数据,才能继续执行。
读channel
数据通过<-
运算符从channel中读取,格式为:data <- channel
,其中data是接收到的数据。如果channel中没有数据可读,则该操作会被阻塞,直到有其他goroutine向channel中写入数据,才能继续执行。
阻塞和非阻塞
channel的读写操作可以分为阻塞和非阻塞两种方式。
阻塞
当channel中没有数据可读、或channel已满无法再写入数据时,读写操作会被阻塞,直到channel中有数据可读、或其他goroutine从channel中读取数据释放出空间后,才能继续执行。
非阻塞
非阻塞读写操作即为尝试读写操作,若无法读写则不会阻塞程序,而是立即返回一个错误。
单向channel
单向channel只能用于发送或者接收数据,不能同时用于读写操作。单向channel是通过指定相应数据类型的读写channel来创建的。
发送channel
可以通过chan<-<T>
指定一个只能发送T类型数据的channel,即只能进行写操作。
接收channel
可以通过<-chan<T>
指定一个只能接收T类型数据的channel,即只能进行读操作。
channel实例
下面是两个channel的使用实例。
实例1:goroutine之间的通信
package main
import (
"fmt"
"time"
)
func task1(ch chan string) {
fmt.Println("task1 start")
time.Sleep(2 * time.Second)
ch <- "task1 done"
}
func task2(ch chan string) {
fmt.Println("task2 start")
time.Sleep(4 * time.Second)
ch <- "task2 done"
}
func main() {
ch := make(chan string)
go task1(ch)
go task2(ch)
res1 := <-ch
res2 := <-ch
fmt.Println(res1)
fmt.Println(res2)
}
这个例子中,我们在两个不同的goroutine中执行两个任务,当任务执行完毕后通过channel返回结果。在main函数中,先创建一个string类型的channel,然后分别启动task1和task2两个函数的goroutine。在这两个函数中,都会先输出开始执行的提示信息,然后分别执行2秒和4秒的休眠,模拟两个不同耗时的任务。任务执行完毕后,将结果写入channel中并通过<-
运算符接收结果。最后在main函数中输出结果。
实例2:带缓冲的channel
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int, 2)
ch <- 1
ch <- 2
fmt.Println("channel is full")
time.Sleep(2 * time.Second)
fmt.Println(<-ch)
fmt.Println(<-ch)
}
这个例子中,我们创建了一个带缓冲的int类型的channel,并将其大小设为2。紧接着,我们向channel中写入两个数字1和2,并输出提示信息“channel is full”,此时channel已经满了。然后通过睡眠2秒的方式模拟程序其他操作,最后通过读channel的方式依次输出之前写入的数字。注意,由于我们设置了缓冲,所以即使channel已经满了,我们依然可以继续向其中写入数据,只有当超过缓冲大小的时候,才会被阻塞。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Go并发编程中使用channel的方法 - Python技术站