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 ها را تشخیص دهید.

 1$ go run -race main.go
 2
 3==================
 4WARNING: DATA RACE
 5Write at 0x00c000522c20 by goroutine 29:
 6  git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq.(*Connection).handleReconnect()
 7      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq/rabbit.go:86 +0x89
 8  git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq.NewConnection.func1()
 9      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq/rabbit.go:35 +0x58
10
11Previous read at 0x00c000522c20 by main goroutine:
12  git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq.NewConnection()
13      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq/rabbit.go:37 +0x324
14  git.ramooz.org/ramooz/golang-components/logger.initializeRabbitMQ()
15      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/logger/rabbit.conn.go:11 +0x226
16  git.ramooz.org/ramooz/golang-components/logger.NewLogger()
17      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/logger/logger.go:37 +0x456
18  ramooz.org/ramooz/user-service/configs.initNewLogger()
19      /home/user/Project/go/ramooz.org/medx/software-builder/configs/configs.go:158 +0x938
20  ramooz.org/ramooz/user-service/configs.ConfigServer()
21      /home/user/Project/go/ramooz.org/medx/software-builder/configs/configs.go:54 +0x15a
22  main.main()
23      /home/user/Project/go/ramooz.org/medx/software-builder/main.go:17 +0x29
24
25Goroutine 29 (running) created at:
26  git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq.NewConnection()
27      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/event-driven/rabbitmq/rabbit.go:35 +0x2da
28  git.ramooz.org/ramooz/golang-components/logger.initializeRabbitMQ()
29      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/logger/rabbit.conn.go:11 +0x226
30  git.ramooz.org/ramooz/golang-components/logger.NewLogger()
31      /home/user/Project/go/ramooz.org/medx/software-builder/vendor/git.ramooz.org/ramooz/golang-components/logger/logger.go:37 +0x456
32  ramooz.org/ramooz/user-service/configs.initNewLogger()
33      /home/user/Project/go/ramooz.org/medx/software-builder/configs/configs.go:158 +0x938
34  ramooz.org/ramooz/user-service/configs.ConfigServer()
35      /home/user/Project/go/ramooz.org/medx/software-builder/configs/configs.go:54 +0x15a
36  main.main()
37      /home/user/Project/go/ramooz.org/medx/software-builder/main.go:17 +0x29
38==================

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