瞅一眼就能学会的GO并发编程使用教程
什么是并发编程
并发编程是指同时执行多个独立的代码片段,这些代码片段可以是进程、线程或协程。并发编程的目标是提高程序的性能和可扩展性。
GO并发编程使用教程
GO语言天生具备良好的并发编程能力,下面是GO并发编程的使用教程。
协程
协程是GO语言特有的轻量级线程,它不是操作系统线程,也不是语言本身实现的线程,而是在语言程序中由用户自主实现的线程。
协程的创建和启动
通过在函数前添加go关键字,就可以在GO语言中创建并启动一个协程:
go func() {
// 这里写协程的逻辑
}()
协程的通信
GO语言中常用的协程通信方式是channel,channel提供了一种线程安全的数据传输方式。
ch := make(chan int)
go func() {
ch <- 123 // 发送数据
}()
num := <- ch // 接收数据
线程安全的使用方式
GO语言中的大部分数据结构和函数都是线程安全的,因此我们可以非常方便地进行并发编程,例如并发地操作slice:
func main() {
var wg sync.WaitGroup
nums := []int{1, 2, 3, 4, 5}
for _, num := range nums {
wg.Add(1)
go func(num int) {
defer wg.Done()
fmt.Println(num * num)
}(num)
}
wg.Wait()
}
在上面的示例中,我们使用sync.WaitGroup
来等待所有协程的执行完成,保证了输出的顺序性。
示例1:并发地读写文件
下面是一个示例,演示了如何同时读取多个文件并写入到同一个文件:
func main() {
var wg sync.WaitGroup
files := []string{"file1.txt", "file2.txt", "file3.txt"}
outputFile := "output.txt"
output, err := os.Create(outputFile)
if err != nil {
panic(err)
}
defer output.Close()
for _, file := range files {
wg.Add(1)
go func(file string) {
defer wg.Done()
input, err := os.Open(file)
if err != nil {
panic(err)
}
defer input.Close()
buf := make([]byte, 1024)
for {
n, err := input.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if n == 0 {
break
}
output.Write(buf[:n])
}
}(file)
}
wg.Wait()
}
在上面的示例中,我们使用了sync.WaitGroup
等待所有协程执行完成,以及文件读取的逻辑和文件写入的逻辑,保证了程序的正确性。
示例2:并发地执行耗时任务
下面是一个示例,演示了如何同时执行多个耗时的任务:
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Printf("worker %d started job %d\n", id, j)
time.Sleep(time.Second)
fmt.Printf("worker %d finished job %d\n", id, j)
results <- j * 2
}
}
func main() {
jobs := make(chan int, 100)
results := make(chan int, 100)
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
for a := 1; a <= 5; a++ {
<-results
}
}
在上面的示例中,我们使用了channel来传递任务和结果,保证了程序的正确性和顺序性。
总结
以上就是GO并发编程的使用教程,希望对大家有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:瞅一眼就能学会的GO并发编程使用教程 - Python技术站