Re: std::deque Thread Saftey Situtation
On Aug 29, 7:45 pm, NvrBst <nvr...@gmail.com> wrote:
Everything I've written is pseudo-code, not my actual
code. I can't get the Indentations right here, and would be too hard
to follow if I just paste, but I can outline the basics:
--Pumping Thread--
WaitForReadSignle();
ReadTCPIP(Buffer, size, ...);
//Copies Buffer, and makes myStruct
m_Q[TCPIP].qLock.Enter();
q.push_back(myStruct);
m_Q[TCPIP].qLock.Leave();
SetEvent(recvieEvent);
--Processing Thread--
WaitForObjects(recvieEvent);
m_Q[TCPIP].qLock.Enter();
while(q.size() > 0) {
myStruct = q.front();
q.pop_front();
m_Q[TCPIP].qLock.Leave();
ProcessData(myStruct);
m_Q[TCPIP].Enter();}
m_Q[TCPIP].Leave();
Both threads are in loops, and there are stuff I left out for clarity,
but this, more-than-less, is the structure. I do have try{} finally{}
blocks set up (to ensure that for every "Enter()" there is a
"Leave()"). I left them out for clarity. ....
Enough try-catch blocks will work, although I'd find proofreading them
a bit much for my taste. A thin wrapper class would get the
proofreading time per instance down to practically instant.
Please pardon my use of agonizing detail in the following. A really
thin wrapper class WrapMutex should:
* take the actual mutex as a non-const reference parameter in its
constructor
* store a reference to the actual mutex as private data
** I think this implies not default-constructable, as a parameter is
needed to initialize the reference. Usually not a good trait, but
acceptable for this class.
* call Enter on the mutex in its inline constructor
* call Leave on the mutex in its inline non-virtual destructor
* not be copyable
** We should lose the default assignment operator because of the
reference data member, but the copy constructor needs to be rendered
unusable. Besides the textbook method, deriving from
boost::noncopyable will work.
Then your code
m_Q[TCPIP].qLock.Enter();
while(q.size() > 0) {
myStruct = q.front();
q.pop_front();
m_Q[TCPIP].qLock.Leave();
ProcessData(myStruct);
m_Q[TCPIP].qLock.Enter();
}
m_Q[TCPIP].qLock.Leave();
can be replaced by
some_struct_type myStruct;
while(q.size() > 0) {
{
WrapMutex(m_Q[TCPIP].qLock);
myStruct = q.front();
q.pop_front();
}
ProcessData(myStruct);
}
As I said, you should look for condition variables. Perhaps boost has
something for you. I am not sure that they have a producer-consumer
class, but they have the building blocks you need, and quite likely
also an example that you can use as a skeleton.
I am confident that there are also other solutions out there.
I'm unsure what boost is,
The main website is http://www.boost.org/ ; it's a very extensive C++
library with a noticeable learning curve. I personally am nonfluent
in it. (I currently use mainly the program-correctness, conditional
compilation of templates, and Boost.Preprocessor sub-libraries.)