第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

并發(fā)寫入文件

并發(fā)寫入文件

Go
繁華開滿天機 2021-10-04 15:37:30
在go中,如何控制并發(fā)寫入文本文件?我問這個是因為我將有多個 goroutine 使用相同的文件處理程序?qū)懭胛谋疚募?。我寫了這段代碼來嘗試看看會發(fā)生什么,但我不確定我是否“正確”做到了:package mainimport (    "os"    "sync"    "fmt"    "time"    "math/rand"    "math")func WriteToFile( i int, f *os.File, w *sync.WaitGroup ){    //sleep for either 200 or 201 milliseconds    randSleep := int( math.Floor( 200 + ( 2 * rand.Float64() ) ) )    fmt.Printf( "Thread %d waiting %d\n", i, randSleep )    time.Sleep( time.Duration(randSleep) * time.Millisecond )    //write to the file    fmt.Fprintf( f, "Printing out: %d\n", i )    //write to stdout    fmt.Printf( "Printing out: %d\n", i )    w.Done()}func main() {    rand.Seed( time.Now().UnixNano() )    d, err := os.Getwd()    if err != nil {        fmt.Println( err )    }    filename := d + "/log.txt"    f, err := os.OpenFile( filename, os.O_CREATE | os.O_WRONLY | os.O_TRUNC, 0666 )    if err != nil {        fmt.Println( err )    }    var w *sync.WaitGroup = new(sync.WaitGroup)    w.Add( 10 )    //start 10 writers to the file    for i:=1; i <= 10; i++ {        go WriteToFile( i, f, w )    }    //wait for writers to finish    w.Wait()}我一半期望輸出會在文件中顯示類似這樣的內(nèi)容,而不是我得到的連貫輸出:Printing Printing out: 2out: 5Poriuntitng: 6從本質(zhì)上講,由于缺乏同步,我預(yù)計角色會出現(xiàn)不連貫和交織的情況。我是否沒有編寫代碼來哄騙這種行為?或者在調(diào)用fmt.Fprintf同步寫入過程中是否有某種機制?
查看完整描述

2 回答

?
慕田峪7331174

TA貢獻1828條經(jīng)驗 獲得超13個贊

控制并發(fā)訪問的一種簡單方法是通過服務(wù) goroutine,從通道接收消息。該 goroutine 將擁有對該文件的唯一訪問權(quán)限。因此,訪問將是順序的,沒有任何競爭問題。

通道在交錯請求方面做得很好??蛻舳藢懭胪ǖ蓝皇侵苯訉懭胛募?。頻道上的消息會自動為您交錯。

與簡單地使用互斥鎖相比,這種方法的好處在于您可以開始將程序視為微服務(wù)的集合。這是 CSP 方式,可以輕松地從較小的組件組合大型系統(tǒng)。


查看完整回答
反對 回復(fù) 2021-10-04
?
繁星coding

TA貢獻1797條經(jīng)驗 獲得超4個贊

有很多方法可以控制并發(fā)訪問。最簡單的方法是使用Mutex:


var mu sync.Mutex


func WriteToFile( i int, f *os.File, w *sync.WaitGroup ){

    mu.Lock()

    defer mu.Unlock()

    // etc...

}

至于為什么你沒有看到問題,Go 使用操作系統(tǒng)調(diào)用來實現(xiàn)文件訪問,并且這些系統(tǒng)調(diào)用是線程安全的(強調(diào)):


根據(jù) POSIX.1-2008/SUSv4 Section XSI 2.9.7(“與常規(guī)文件操作的線程交互”):


在 POSIX.1-2008 中指定的效果中,當它們對常規(guī)文件或符號鏈接進行操作時,以下所有函數(shù)都應(yīng)該是原子的: ...


隨后列出的 API 包括 write() 和 writev(2)??缇€程(和進程)應(yīng)該是原子的,其中包括文件偏移的更新。但是,在 3.14 版之前的 Linux 上,情況并非如此:如果共享打開文件描述(請參閱 open(2))的兩個進程同時執(zhí)行 write()(或 writev(2)),則 I /O 操作在更新文件偏移量方面不是原子的,因此兩個進程輸出的數(shù)據(jù)塊可能(錯誤地)重疊。 此問題已在 Linux 3.14 中修復(fù)。


我仍然會使用鎖,因為 Go 代碼不是自動線程安全的。(兩個 goroutine 修改同一個變量會導(dǎo)致奇怪的行為)


查看完整回答
反對 回復(fù) 2021-10-04
  • 2 回答
  • 0 關(guān)注
  • 241 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號