views:

120

answers:

2

I have a collection of the form:

map<key, list<object> >

I only ever insert at the back of the list and sometimes I read from the entire map (but I never write to the map, except at initialization).

As I understand it, none of the STL containers are thread safe, but I can only really have a maximum of one thread per key. Am I missing anything in assuming I'll be pretty safe with this arrangement?

+1  A: 

TBH as long as you put a critical section around any write and read it will work fine.

Goz
+7  A: 

If the map is never modified at all during the multi-threaded scenario, then you're fine. If each thread looks at its own list, then that's thread-private data, so you're also fine.

Take care not to try and lookup keys with [] because that will insert (modify) if the key doesn't exist in the map yet.

However, I'm curious as to why you'd need this structure - why not keep a pointer/reference or the actual list object itself on the stack of each thread, given that it's private to each thread?

(If it's not, then you need proper synchronisation on the list.)

In fact you say you "read from the entire map" - presumably meaning that any random thread may try to iterate through any of the lists. So you definitely need to synchronise operations on the lists.

Daniel Earwicker
+1 I agree. It should be better to have an explicit structure that endorse the fact that only one thread access a key or use synchro. The problem if you keep things this way is that someone will sooner or later use your code (even you later) and forget the "one key-one thread requirement" leading to awful bugs ...
neuro
I don't know. It's kindof like a poor man's cache. The real problem is we have some shitty wannabe here messing with our database and causing table locks on critical data using Access front ends (yes, I know). Unfortunately he is good friends with the President so no one can tell him not to cause these problems without being fired, so I got tired of the problem and wanted to cache some of the data by employee in memory on another machine that no one can touch so that it would queue and hold to update the database if it were unavailable due to this idiot's constant locking.
Oh, as for "reading through the entire map" that's done by a watcher thread to locate dirty inserts or updates and write them back to the database. That part is also single-threaded, so the only problem I can see is an insert during a scan. Maybe that's where the syncronization is needed... Hmm.
Sounds like you want to use the simplest possible implementation. Given that you already have a locking nightmare, micro-performance isn't an issue but correctness is. So I wouldn't leave ANYTHING to chance. Use deque as your internal structure but hide it inside a much simpler push-pop queue wrapper class and protect the push/pop operations with a critical section.
Daniel Earwicker
(I suggest deque just because it happens to be ideal for a queue, if that's what you need).
Daniel Earwicker
Yes, I thought about doing that. Queue for the inserts and updates, hold if unable to commit, mainly because it will eliminate the nested loops and, like you said, probably be easier to manage.Thanks, everyone.