写入文件
import (
"fmt"
"os"
"strconv"
"time"
)
func writeLog(i int, ch chan int) {
file, err := os.OpenFile("config.txt", os.O_RDWR|os.O_APPEND, 0776)
defer file.Close()
if err != nil {
panic(err)
}
file.WriteString("写入文件--" + strconv.Itoa(i) + "\n")
ch <- i
}
func main() {
fmt.Println("开始------")
start := time.Now().UnixNano()
ch := make(chan int, 5)
for i := 1; i <= 5; i++ {
go writeLog(i, ch)
}
<- ch
end := time.Now().UnixNano()
fmt.Println("结束------", (end-start)/1e6)
}
循环5次去写入文件。这种写法会有一个问题,当执行的时候,文件中的内容理论上来讲应该是
写入文件--5
写入文件--2
写入文件--1
写入文件--4
写入文件--3
但实际情况是,每次写的数量不固定(这可能是因为主线程执行完成,但是开启的goroutine还没跑完)
所以,修改下main,使用range遍历通道消息
func main() {
fmt.Println("开始------")
start := time.Now().UnixNano()
ch := make(chan int)
for i := 1; i <= 5; i++ {
go writeLog(i, ch)
}
for s := range ch {
fmt.Println(<-ch)
}
end := time.Now().UnixNano()
fmt.Println("结束------", (end-start)/1e6)
}
此时,写文件的操作不会"丢失"了,但是程序会报错:fatal error: all goroutines are asleep - deadlock!
就是说,死锁了!因为range在通道不关闭的时候自己也不会停止读取,但是这个时候通道并没有内容可以给他读取了,所以就会阻塞当前goroutines,其结果就是死锁。
现在再修改main,使用缓冲通道
func main() {
fmt.Println("开始------")
start := time.Now().UnixNano()
ch := make(chan int, 5)
for i := 1; i <= 5; i++ {
go writeLog(i, ch)
}
for j := 0; j < 5; j++ {
fmt.Println(<-ch)
}
end := time.Now().UnixNano()
fmt.Println("结束------", (end-start)/1e6)
}
好了,消停了,写入数量正常了,也不死锁了。