linux

Golang日志如何实现并发安全

小樊
44
2025-12-07 08:23:59
栏目: 编程语言

在Golang中,实现并发安全的日志记录可以通过以下几种方式:

  1. 使用sync.Mutex或sync.RWMutex:

    你可以使用sync.Mutex或sync.RWMutex来确保在同一时间只有一个goroutine可以访问日志记录器。这是一个简单的示例:

package main

import (
	"fmt"
	"log"
	"os"
	"sync"
)

type SafeLogger struct {
	logger *log.Logger
	mu     sync.Mutex
}

func (l *SafeLogger) Log(msg string) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.logger.Println(msg)
}

func main() {
	safeLogger := &SafeLogger{
		logger: log.New(os.Stdout, "", log.LstdFlags),
	}

	var wg sync.WaitGroup
	wg.Add(2)

	go func() {
		defer wg.Done()
		safeLogger.Log("Hello from goroutine 1")
	}()

	go func() {
		defer wg.Done()
		safeLogger.Log("Hello from goroutine 2")
	}()

	wg.Wait()
}
  1. 使用sync.Once:

    如果你只需要确保某个操作只执行一次,可以使用sync.Once。这对于初始化日志记录器等一次性操作非常有用。

package main

import (
	"log"
	"os"
	"sync"
)

type OnceLogger struct {
	logger *log.Logger
	once   sync.Once
}

func (l *OnceLogger) Log(msg string) {
	l.once.Do(func() {
		l.logger.Println(msg)
	})
}

func main() {
	onceLogger := &OnceLogger{
		logger: log.New(os.Stdout, "", log.LstdFlags),
	}

	var wg sync.WaitGroup
	wg.Add(2)

	go func() {
		defer wg.Done()
		onceLogger.Log("Hello from goroutine 1")
	}()

	go func() {
		defer wg.Done()
		onceLogger.Log("Hello from goroutine 2")
	}()

	wg.Wait()
}
  1. 使用第三方日志库:

    有许多第三方日志库已经实现了并发安全,例如zap、logrus等。这些库通常提供了高性能和易用性,你可以根据需要选择合适的库。

例如,使用zap库:

package main

import (
	"go.uber.org/zap"
	"sync"
)

func main() {
	logger, _ := zap.NewProduction()
	defer logger.Sync()

	var wg sync.WaitGroup
	wg.Add(2)

	go func() {
		defer wg.Done()
		logger.Info("Hello from goroutine 1")
	}()

	go func() {
		defer wg.Done()
		logger.Info("Hello from goroutine 2")
	}()

	wg.Wait()
}

总之,实现并发安全的日志记录可以通过使用互斥锁、sync.Once或第三方日志库来完成。在实际应用中,你可以根据自己的需求选择合适的方法。

0
看了该问题的人还看了