معمولا تو بحث همزمانی یکی از اتفاقاتی که خیلی ممکن است رخ دهد بحث data race است و data race زمانی رخ می دهد که ۲ یا چند گوروتین قصد دارند به یک آدرس حافظه در یک زمان دسترسی داشته باشند. حال اگر ما جلوی data race را نگیریم ممکن است تغییرات نادرست برروی مقادیر داخل خانه حافظه صورت گیرد.
راه هایی برای مقابله با data race وجود دارد که به شرح زیر است :
- استفاده از Mutex داخل پکیج sync برای قفل گذاشتن/برداشتن یک بخش دیتا.
- استفاده RWMutex داخل پکیج sync می توانید داده اشتراک گذاری شده را قفل کنید فقط یک گوروتین عملیات نوشتن داشته باشد.
- استفاده از پکیج 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 داده است که در فلان خط کد شما فلان گوروتین ها در یک زمان دسترسی برروی یک داده را دارند. و شما با توجه به خروجی می توانید سناریو های جلوگیری را انجام دهید.