69 lines
1.5 KiB
Go
69 lines
1.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// SafeWriter 线程安全的Writer封装
|
|
type SafeWriter struct {
|
|
writer *os.File
|
|
mu sync.Mutex // 互斥锁,保护Writer写入
|
|
}
|
|
|
|
// NewSafeWriter 创建SafeWriter实例
|
|
func NewSafeWriter(filename string) (*SafeWriter, error) {
|
|
file, err := os.OpenFile(filename,
|
|
os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &SafeWriter{writer: file}, nil
|
|
}
|
|
|
|
// Writef 线程安全的格式化写入
|
|
func (w *SafeWriter) Writef(format string, args ...interface{}) error {
|
|
w.mu.Lock() // 加锁,独占写入权
|
|
defer w.mu.Unlock() // 函数退出自动解锁
|
|
|
|
// 拼接日志前缀(时间)+ 格式化内容
|
|
logContent := fmt.Sprintf("[%s] %s\n",
|
|
time.Now().Format("2006-01-02 15:04:05"),
|
|
fmt.Sprintf(format, args...))
|
|
|
|
// 写入文件(用WriteString比Fprintf更高效)
|
|
_, err := w.writer.WriteString(logContent)
|
|
return err
|
|
}
|
|
|
|
// Close 关闭文件
|
|
func (w *SafeWriter) Close() error {
|
|
return w.writer.Close()
|
|
}
|
|
|
|
func main() {
|
|
writer, err := NewSafeWriter("concurrent.log")
|
|
if err != nil {
|
|
fmt.Printf("SafeWriter创建失败:%v\n", err)
|
|
return
|
|
}
|
|
defer writer.Close()
|
|
|
|
var wg sync.WaitGroup
|
|
// 10个goroutine并发写入(每个写10条)
|
|
for i := 0; i < 10; i++ {
|
|
wg.Add(1)
|
|
go func(goroutineID int) {
|
|
defer wg.Done()
|
|
for j := 0; j < 10; j++ {
|
|
writer.Writef("goroutine%d:完成第%d条任务", goroutineID, j)
|
|
}
|
|
}(i)
|
|
}
|
|
|
|
wg.Wait()
|
|
fmt.Println("10个goroutine并发写入完成,内容无错乱")
|
|
}
|