This project I'm working on potentially has a lot of objects in a multithreading environment. These objects are reading from a handful of resources. For example, say I have 1000 objects reading from any one of 100 resources at a time. Objects may try to read from a resource at any time, but I need to prevent multiple objects from reading the same resource at the same time (ie: need to block with mutexes)
Due to the respectable number of resources I'm dealing with, this has me wondering just how expensive mutex creation can be. The way I see it I have 2 general approaches:
1) One "master" mutex for everything, that every object locks before reading from any resource.
2) One mutex for each resource.
#1 obviously isn't ideal because it would block needlessly (even when two objects are reading from separate resources)
#2 seems like the better approach, but we could be talking about hundreds of mutexes! (or maybe even thousands -- although that's not likely) Would that be terribly expensive computation or memory-wise?
Obviously the details would depend on the threading lib used, but I'm looking for more of a general idea. Currently I'm using SDL threads (which appear to use pthread internally, at least on my system).
Don't worry about memory.
Let's suppose SDL uses a particularly large mutex: 64 bytes. That's quite large for something that just needs to store a state and maybe a couple other things. To store the mutexes for 100,000 resources, 1K each, you'd need 640,000 bytes, not counting the structure you store them in. I don't think 640k is something you need to worry about when you're already using 100 MB.
Do it right the right way.
If you're just going to read, you don't need to lock the resource with a mutex, just be sure you all access to the resource passes through one and only one function, or the next step will be harder. If there's any chance that the resource could be written, you need to lock it, or you risk end up debugging a race condition. You can trust me you don't want to do that.
I was more worried about CPU time concerns than memory usage (ie: does actually generating a mutex incur some hidden penalty -- could generating 1000 mutexes make my program hang for a few seconds -- though I suppose that'd be simple enough to test on my own... haw)
Re: locking on reading, there may be actual state changes involved in the read, so they do need to be behind mutexes (this is for sort of a file decompression and cache system, where reading may involve writing cache data to disk, and possibly modifying a file that some other object is reading from).
Thanks helios! You post really does just make me feel a lot more comfortable about my approach. Sometimes I get all worked up over nothing.
Allocation time is insignificant, as well.
The only problem with mutexes time-wise is that (most likely depending on how the OS implements them) they seem to take the granularity of the OS sleep function to lock on average. For example, a Windows mutex takes 10 ms to lock, on average.