Re: TCP posix thread buffer question across threads
On Jul 5, 5:39 pm, Bob <j...@rahul.net> wrote:
I have an odd situation that I didnt expect, so I probably
dont understand enough which is why Im asking here.
I have created a multithreaded TCP server which has the
following buffer in each thread:
tcpThread.h:
unsigned char in_buffer[MAX_TCP_BUF];
tcpThread.cpp:
size_t n = read(fd, in_buffer, MAX_TCP_BUF];
PROBLEM:
This is under linux. I only have 2 clients connected, so each
has its own pthread() of the above, but I see in_buffer[]
occasionally getting characters and/or leftover characters
from the other client in the 'in_buffer'.
I changed the code to make in_buffer[] a static array in the
.cpp file instead and I believe that has solved the problem,
but I would like to further understand the problem.
I had thought that having it in the .h file just meant that as
each thread was created, it had its own address of the array,
but apparently thats not the case?
There is no thread local storage in C++ (at least not
currently). Objects can have static, auto or dynamic lifetimes,
but any given instance of an object is the same everywhere. (In
some ways, this is the very definition of what is meant by
threading, as opposed to separate processes.) Linux and other
Unix (and I believe Windows as well, and probably most other
systems) do have a provision for thread local storage, but it's
relatively complicated to use, and not necessarily very
performant, see pthread_getspecific and pthread_setspecific.
(Basically, one legal implementation would be to use something
like std::map, indexed on the thread id and the object key.)
The usual solution is to only use local variables, since each
time you enter the block, you get a new instance of any local
variables. Be careful with regards to stack size if you do this
for buffers, however; you'd probably be better off using
std::vector< unsigned char >, rather than a C style array.
Also, depending on what you're doing, a better solution is often
to use a separate process, rather than a separate thread, for
each connection. I know that threads are in, and separate
processes aren't, but unless the connections are sharing a lot
of data, the separate process model is a lot more robust. And
since you have a separate program execution per process, you
have separate instances of everything in each process. The Unix
process model works particularly well for this one particular
case.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34