go 解决处理读写文件时的并发问题导致宏机错误

    技术2022-07-11  81

    简单粗暴:sync.Mutex 解决问题:

    goroutine 19285 [semacquire]: internal/poll.runtime_Semacquire(0xc00008c28c) D:/tools/Go/src/runtime/sema.go:61 +0x49 internal/poll.(*fdMutex).rwlock(0xc00008c280, 0x0, 0x20300be) D:/tools/Go/src/internal/poll/fd_mutex.go:154 +0xb4 internal/poll.(*FD).writeLock(...) D:/tools/Go/src/internal/poll/fd_mutex.go:239 internal/poll.(*FD).Write(0xc00008c280, 0xc0168bf880, 0x9, 0x20, 0x0, 0x0, 0x0) D:/tools/Go/src/internal/poll/fd_windows.go:684 +0x65 os.(*File).write(...) D:/tools/Go/src/os/file_windows.go:230 os.(*File).Write(0xc000006018, 0xc0168bf880, 0x9, 0x20, 0x8, 0xc00a6e3e98, 0x409562) D:/tools/Go/src/os/file.go:153 +0x78 fmt.Fprintln(0x4f2ec0, 0xc000006018, 0xc00a6e3f80, 0x1, 0x1, 0xc041a849d8, 0x8, 0x0) D:/tools/Go/src/fmt/print.go:265 +0x92 fmt.Println(...) D:/tools/Go/src/fmt/print.go:274 main.readAndWriteLog(0xc005f41ce0, 0x7) D:/workspaces/go/src/gihub.com/lbw/main/main.go:22 +0x311 created by main.main D:/workspaces/go/src/gihub.com/lbw/main/main.go:32 +0x18a package main import ( "fmt" "os" "sync" "time" ) var logSync sync.Mutex //读写一个文件追加日志 func readAndWriteLog(add_data string) { fmt.Println("this string is:", add_data) f, _ := os.OpenFile("D:/a.txt", os.O_RDWR|os.O_APPEND, 0777) //读写模式打开,写入追加 defer f.Close() num, _ := f.Write([]byte(add_data + "\n")) //模拟执行时间 time.Sleep(1000000000) fmt.Println(fmt.Sprintf(add_data+"%d", num)) } func main() { for i := 0; i < 10000; i++ { //启动协程 go readAndWriteLog(fmt.Sprintf("ABC%d", i)) } for i := 0; i < 10000; i++ { go readAndWriteLog(fmt.Sprintf("ABC%d", i)) } for i := 0; i < 10000; i++ { go readAndWriteLog(fmt.Sprintf("ABC%d", i)) } for i := 0; i < 10000; i++ { go readAndWriteLog(fmt.Sprintf("ABC%d", i)) } for i := 0; i < 10000; i++ { go readAndWriteLog(fmt.Sprintf("ABC%d", i)) } for i := 0; i < 10000; i++ { go readAndWriteLog(fmt.Sprintf("ABC%d", i)) } for i := 0; i < 10000; i++ { go readAndWriteLog(fmt.Sprintf("ABC%d", i)) } for i := 0; i < 10000; i++ { go readAndWriteLog(fmt.Sprintf("ABC%d", i)) } for i := 0; i < 10000; i++ { go readAndWriteLog(fmt.Sprintf("ABC%d", i)) } for i := 0; i < 10000; i++ { go readAndWriteLog(fmt.Sprintf("ABC%d", i)) } for i := 0; i < 10000; i++ { go readAndWriteLog(fmt.Sprintf("ABC%d", i)) } for i := 0; i < 10000; i++ { go readAndWriteLog(fmt.Sprintf("ABC%d", i)) } time.Sleep(100000000000) }

    解决方案加锁:

    package main import ( "fmt" "os" "sync" "time" ) var logSync sync.Mutex //读写一个文件追加日志 func readAndWriteLog(add_data string) { fmt.Println("this string is:", add_data) logSync.Lock() f, _ := os.OpenFile("D:/a.txt", os.O_RDWR|os.O_APPEND, 0777) //读写模式打开,写入追加 defer f.Close() num, _ := f.Write([]byte(add_data + "\n")) //模拟执行时间 time.Sleep(1000000000) logSync.Unlock() fmt.Println(fmt.Sprintf(add_data+"%d", num)) }
    Processed: 0.018, SQL: 12