Quantcast
Channel: cc :: somkiat
Viewing all articles
Browse latest Browse all 1997

Golang :: เจอปัญหาเรื่อง concurrency ข้อมูลที่เก็บใน Map

$
0
0

วันนี้ทำการเขียน RESTful API ด้วยภาษา Go
ซึ่งมีการใช้ข้อมูลร่วมกัน จัดเก็บในรูปแบบของ map
การทำงานนั้นเป็นปกติมาก ๆ
แต่เมื่อทำการลองยิง performance ดูหน่อยเท่านั้น
ก็เจอ Runtime error ดังนี้
fatal error: concurrent map read and map write

[gist id="c306d337225ebe020e0336942e86409f" file="1.txt"]

เริ่มจาก code ที่เป็นปัญหาดังนี้

ซึ่งใช้งานข้อมูลจากตัวแปรชนิด map

[gist id="c306d337225ebe020e0336942e86409f" file="1.go"]

เป็น code ชุดที่เกิดปัญหานั่นเอง
ก็ลองไปหาต้นเหตุ ก็เจอว่า map นั้น
ไม่ปลอดภัยสำหรับการแก้ไขข้อมูลพร้อม ๆ กัน
แต่ถ้าอ่านอย่างเดียวไม่เป็นไร

การแก้ไขปัญหานี้แบบง่าย ๆ คือ

ถ้าทำการแก้ไขพร้อม ๆ กัน
ดังนั้นก็ lock/unlock หรือ Mutex กันไปเลย
สามารถแก้ไขปัญหาได้ แต่แลกมาด้วยความเร็วที่ช้าลง
แต่เป็นวิธีการที่ง่ายนะ เขียน code ได้ดังนี้ 
เพิ่มนิดเดียว

[gist id="c306d337225ebe020e0336942e86409f" file="2.go"]

หรืออาจจะนำ go channel เข้ามาใช้เพื่อแก้ไขปัญหานี้ก็ได้นะ

ซึ่งก็เพิ่มความซับซ้อนขึ้นมาอีกหน่อย ดังนี้

[gist id="c306d337225ebe020e0336942e86409f" file="3.go"]

หรืออาจจะใช้ sync map ที่ทาง Go ได้เตรียมมาให้

ก็สามารถแก้ไขปัญหาได้เช่นกัน

[gist id="c306d337225ebe020e0336942e86409f" file="4.go"]

ทั้งสามวิธีสามารถแก้ไขปัญหาได้

มาดูผลการทดสอบ performance ทั้งสองกันบ้าง

[gist id="c306d337225ebe020e0336942e86409f" file="compare.txt"]

ขอให้สนุกกับการเขียน code นะครับ


Viewing all articles
Browse latest Browse all 1997

Trending Articles