3.5 آموزش مقابله با data race

3.5 آموزش مقابله با data race

معمولا تو بحث همزمانی یکی از اتفاقاتی که خیلی ممکن است رخ دهد بحث data race است و data race زمانی رخ می دهد که ۲ یا چند گوروتین قصد دارند به یک آدرس حافظه در یک زمان دسترسی داشته باشند. حال اگر ما جلوی data race را نگیریم ممکن است تغییرات نادرست برروی مقادیر داخل خانه حافظه صورت گیرد.

راه هایی برای مقابله با data race وجود دارد که به شرح زیر است :

  1. استفاده از Mutex داخل پکیج sync برای قفل گذاشتن/برداشتن یک بخش دیتا.
  2. استفاده RWMutex داخل پکیج sync می توانید داده اشتراک گذاری شده را قفل کنید فقط یک گوروتین عملیات نوشتن داشته باشد.
  3. استفاده از پکیج atomic برای عملیات بصورت atomic برروی مقادیر.

3.5.1 تشخیص Data Race #

به لطف امکان جانبی زبان گو شما می توانید خیلی راحت بخش هایی که data race رخ داده را تشخیص دهید. کافیه سوییچ race- را هنگام build اضافه کنید تا در زمان data race ها را تشخیص دهید.

$ go run -race main.go

==================
WARNING: DATA RACE
Write at 0x00c000522c20 by goroutine 29:
  git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq.(*Connection).handleReconnect()
      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq/rabbit.go:86 +0x89
  git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq.NewConnection.func1()
      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq/rabbit.go:35 +0x58

Previous read at 0x00c000522c20 by main goroutine:
  git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq.NewConnection()
      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq/rabbit.go:37 +0x324
  git.ramooz.org/ramooz/golang-components/logger.initializeRabbitMQ()
      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/logger/rabbit.conn.go:11 +0x226
  git.ramooz.org/ramooz/golang-components/logger.NewLogger()
      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/logger/logger.go:37 +0x456
  ramooz.org/ramooz/user-service/configs.initNewLogger()
      /home/user/Project/go/ramooz.org/medx/software-builder/configs/configs.go:158 +0x938
  ramooz.org/ramooz/user-service/configs.ConfigServer()
      /home/user/Project/go/ramooz.org/medx/software-builder/configs/configs.go:54 +0x15a
  main.main()
      /home/user/Project/go/ramooz.org/medx/software-builder/main.go:17 +0x29

Goroutine 29 (running) created at:
  git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq.NewConnection()
      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq/rabbit.go:35 +0x2da
  git.ramooz.org/ramooz/golang-components/logger.initializeRabbitMQ()
      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/logger/rabbit.conn.go:11 +0x226
  git.ramooz.org/ramooz/golang-components/logger.NewLogger()
      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/logger/logger.go:37 +0x456
  ramooz.org/ramooz/user-service/configs.initNewLogger()
      /home/user/Project/go/ramooz.org/medx/software-builder/configs/configs.go:158 +0x938
  ramooz.org/ramooz/user-service/configs.ConfigServer()
      /home/user/Project/go/ramooz.org/medx/software-builder/configs/configs.go:54 +0x15a
  main.main()
      /home/user/Project/go/ramooz.org/medx/software-builder/main.go:17 +0x29
==================

در خروجی بالا یک هشدار data race داده است که در فلان خط کد شما فلان گوروتین ها در یک زمان دسترسی برروی یک داده را دارند. و شما با توجه به خروجی می توانید سناریو های جلوگیری را انجام دهید.