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)//每循環一次就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))
??????//此處在一次循環結束時,數據已經讀出并保存在sortResults中了,
??????//?為什么后面緊接著file.Close()會導致整個數據都讀不出來了呢?
??????file.Close()??//close與open都在循環體內
???}
???return?zzpipeline.MergeN(sortResults...)
}
2020-10-28
11分45秒的時候老師解釋了,createPipeline只是創建了pipeline,也就是把一個文件分成了chunkCount個小快,各放上了一個channel,但是此時channel還是阻塞的,因為要等觸發了ReadSource以后才這些通道才會開始不斷傳輸。因此在CreatePipeline里面是不能file.close的,需要把這些file句柄返回出來,由外面close。老師說因為不想把這個示例搞的太復雜,所以就留下了這個坑。
2019-06-18
若要加bufio就要把open移到循環體里來
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 不可靠還體現在:若是在循環后sleep個幾秒鐘,最終處理到560m左右的數據,file就會被關閉。如果在循環體里打印的話,可以發現這4次循環瞬間就完成了。而數據還沒開始處理。所以不能在生產完管道后就立馬關閉file,必須等所有事情處理完才能file.Close()。所以不能在函數內關閉,要把[]*File傳到外面去關閉。
2018-10-04
2018-10-04
這要從生命周期來考慮,這個函數只是生成pipeline,管道還沒開始運行,就把file關閉了,當然就取不出數據啊。
2018-08-22
能想到的大概兩個原因:
每次都開關是有性能損耗的,打開和關閉需要耗時;但這個并不是關鍵的。
每次需要存儲讀到的位置,下次打開時,還要從上次的地方開始讀??;這會增加程序的復雜讀,這里跟數據庫的長連接情況方便查詢不一樣。? 打開一次足夠的。