func?createPipeline(
???filename?string,
???fileSize,?chunkCount?int)??<-?chan?int{
???chunkSize?:=?fileSize/chunkCount
???sortResults?:=?[]?<-chan?int{}
???for?i:=?0;?i<?chunkCount;i++{
??????file,?err?:=?os.Open(filename)//每循環(huán)一次就open一次file
??????if?err?!=?nil{
?????????panic(err)
??????}
??????file.Seek(int64(i*chunkSize),0)
??????source?:=?zzpipeline.ReaderSource(
?????????bufio.NewReader(file),?chunkSize)
??????sortResults?=?append(sortResults,
?????????zzpipeline.InMemSort(source))
??????//此處在一次循環(huán)結(jié)束時,數(shù)據(jù)已經(jīng)讀出并保存在sortResults中了,
??????//?為什么后面緊接著file.Close()會導(dǎo)致整個數(shù)據(jù)都讀不出來了呢?
??????file.Close()??//close與open都在循環(huán)體內(nèi)
???}
???return?zzpipeline.MergeN(sortResults...)
}
2020-10-28
11分45秒的時候老師解釋了,createPipeline只是創(chuàng)建了pipeline,也就是把一個文件分成了chunkCount個小快,各放上了一個channel,但是此時channel還是阻塞的,因為要等觸發(fā)了ReadSource以后才這些通道才會開始不斷傳輸。因此在CreatePipeline里面是不能file.close的,需要把這些file句柄返回出來,由外面close。老師說因為不想把這個示例搞的太復(fù)雜,所以就留下了這個坑。
2019-06-18
若要加bufio就要把open移到循環(huán)體里來
func createPipeline(filename string, fileSize ,
chunkSize int) ( <-chan int){
readSize := fileSize/chunkSize
pipeline.Init()
sources := [] <-chan int{}
for i := 0; i < chunkSize; i++ {
file, err := os.Open(filename)
if err != nil{
panic(err)
}
file.Seek(int64(i*readSize),0)
source := pipeline.ReadSource(bufio.NewReader(file), readSize)
sort := pipeline.InMemSort(source)
sources = append(sources, sort)
fmt.Printf("n:%d\n", i)
}
return pipeline.MergeN(sources...)
}
2019-06-18
func createPipeline(filename string, fileSize ,
chunkSize int) ( <-chan int, *os.File){
file, err := os.Open(filename)
if err != nil{
panic(err)
}
readSize := fileSize/chunkSize
sources := [] <-chan int{}
for i := 0; i < chunkSize; i++ {
source := pipeline.ReadSource(file, readSize)
sort := pipeline.InMemSort(source)
sources = append(sources, sort)
}
return pipeline.MergeN(sources...), file
} //這樣就把file傳出去close了,看了不點個贊嗎?
2018-10-04
這樣加defer 不可靠還體現(xiàn)在:若是在循環(huán)后sleep個幾秒鐘,最終處理到560m左右的數(shù)據(jù),file就會被關(guān)閉。如果在循環(huán)體里打印的話,可以發(fā)現(xiàn)這4次循環(huán)瞬間就完成了。而數(shù)據(jù)還沒開始處理。所以不能在生產(chǎn)完管道后就立馬關(guān)閉file,必須等所有事情處理完才能file.Close()。所以不能在函數(shù)內(nèi)關(guān)閉,要把[]*File傳到外面去關(guān)閉。
2018-10-04
2018-10-04
這要從生命周期來考慮,這個函數(shù)只是生成pipeline,管道還沒開始運行,就把file關(guān)閉了,當(dāng)然就取不出數(shù)據(jù)啊。
2018-08-22
能想到的大概兩個原因:
每次都開關(guān)是有性能損耗的,打開和關(guān)閉需要耗時;但這個并不是關(guān)鍵的。
每次需要存儲讀到的位置,下次打開時,還要從上次的地方開始讀取;這會增加程序的復(fù)雜讀,這里跟數(shù)據(jù)庫的長連接情況方便查詢不一樣。? 打開一次足夠的。