寫(xiě)入文件
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("寫(xiě)入文件--" + strconv.Itoa(i) + "\n")
ch <- i
}
func main() {
fmt.Println("開(kāi)始------")
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("結(jié)束------", (end-start)/1e6)
}
循環(huán)5次去寫(xiě)入文件。這種寫(xiě)法會(huì)有一個(gè)問(wèn)題洋满,當(dāng)執(zhí)行的時(shí)候剩晴,文件中的內(nèi)容理論上來(lái)講應(yīng)該是
寫(xiě)入文件--5
寫(xiě)入文件--2
寫(xiě)入文件--1
寫(xiě)入文件--4
寫(xiě)入文件--3
但實(shí)際情況是锣咒,每次寫(xiě)的數(shù)量不固定(這可能是因?yàn)橹骶€程執(zhí)行完成,但是開(kāi)啟的goroutine還沒(méi)跑完)
所以赞弥,修改下main毅整,使用range遍歷通道消息
func main() {
fmt.Println("開(kāi)始------")
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("結(jié)束------", (end-start)/1e6)
}
此時(shí),寫(xiě)文件的操作不會(huì)"丟失"了绽左,但是程序會(huì)報(bào)錯(cuò):fatal error: all goroutines are asleep - deadlock!
就是說(shuō)悼嫉,死鎖了!因?yàn)閞ange在通道不關(guān)閉的時(shí)候自己也不會(huì)停止讀取拼窥,但是這個(gè)時(shí)候通道并沒(méi)有內(nèi)容可以給他讀取了戏蔑,所以就會(huì)阻塞當(dāng)前goroutines,其結(jié)果就是死鎖鲁纠。
現(xiàn)在再修改main总棵,使用緩沖通道
func main() {
fmt.Println("開(kāi)始------")
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("結(jié)束------", (end-start)/1e6)
}
好了,消停了改含,寫(xiě)入數(shù)量正常了情龄,也不死鎖了。