c++ - Pointer to STL Container Thread Safety (Queue/Deque) -
i have bit of multi-threading conundrum. have 2 threads, 1 reads serial data, , attempts extracts packets data. 2 threads share queue. thread attempts create packets has function entitled parse following declaration:
parse(std::queue<uint8_t>* data, pthread_mutex_t* lock); essentially takes pointer stl queue , uses pop() goes through queue looking packet. lock used since pop() locked , lock shared between parse function , thread pushing data onto queue. way, queue can parsed while data being actively added it.
the code seems work part, i'm seeing invalid packets @ higher rate i'd expect. main question i'm wondering if pointer changing while i'm reading data out of queue. example, if first thread pushes bunch of data, there chance queue found in memory can change? or guaranteed pointer queue remain constant, data added? concern memory queue can reallocated during parse() function, , therefore in middle of function, pointer invalidated.
for example, understand stl iterators invalidated operations. however, passing pointer container itself. is, this:
// somewhere in code create queue std::queue<uint8_t> queue; // elsewhere... parse(&queue, &lock_shared_between_the_two_threads); does pointer container ever invalidated? , point to? first element, or ...?
note i'm not pointing given element, container itself. also, never specified underlying container should used implement queue, underneath all, it's deque.
any appreciated.
edit 8/1:
i able run few tests on code. couple of points:
the pointer container not change on lifecycle of program. makes sense since queue member variable of class. is, while queue's elements dynamically allocated, not appear case queue itself.
the bad packets experiencing appear function of serial data i'm receiving. dumped data hex file , able find packets invalid, , alogrithm correctly marking them such.
as result, i'm thinking passing reference or pointer stl container function thread safe, i'd hear more commentary ensuring case, or if implementation specific (as alot of stl is...).
you worried modifying container (adding/deleting nodes) in 1 thread somehow invalidate pointer container in thread. container abstraction , remain valid unless delete container object itself. memory data maintained containers typically allocated on heap stl::allocators.
this quite different memory allocated container object can on stack, heap etc., based on how container object created. separation of container allocator what's preventing modification data modifying container object itself.
to make debugging problem simpler, jonathan reinhart suggests, make single threaded system, reads stream , parses it.
on side note, have considered using boost lookfree queues or similar. designed type of scenarios. if receiving packets/reading them frequently, locking queue reading/writing each packet can become significant performance overhead.
Comments
Post a Comment