Steve Wu
Steve Wu

Reputation: 193

Go concurrency: Is it a ideal practice using gob.encode or json.Marshal to avoid lock overhead?

I have a big and deeply nested shared struct. Each goroutine of my program may use a different part of the struct, a slice, a map, etc. To make things worse, all these goroutines do long operations, which means it may not be a good idea to use a big lock for that shared struct. Therefore, I have come up with an idea which is to lock the struct before accessing one part of the struct and then encode it, as soon as the encoding is done the goroutine can release the lock and decodes the data. In this way, one single goroutine won't hold the lock for a long time. The question is: I'm not sure if this is a good practice, is there a better way to solve this kind of problem? Or is there any better ideology to such kinds of problems?

Upvotes: -1

Views: 524

Answers (1)

Jaroslaw
Jaroslaw

Reputation: 656

You may use following techniques instead of sync.Mutex:

  • sync.RWMutex - read-write lock allows to read the structure by multiple goroutine at the same time and only when write lock is not acquired. If your problem is that multiple goroutines cannot code different parts of struct in parallel, this may be the best choice.
  • You can granulate locks as you mentioned in the question, but you must be careful to properly acquire all involved locks to preserve consistency when you modify different parts of the struct.
  • You can take a snapshot of the interesting part of struct under lock and outside lock do some heavy read operation. This will of course put extra pressure on the GC, but it may be worth it.

You could also mix them to achieve better results.

Upvotes: 0

Related Questions