Currently i am developing a (multithreaded) program in C++ which uses Pro*C.
I already have it runing on windows NT, now i am porting it to Unix ( Dec
Alpha ). The program basically starts up a thread that performs database
retrieves and updates. The main thread passes all the commands to be
performed by the database thread in a piece of shared memory. The database
thread gets the data from the shared memory, performs the database action,
and puts the result back in the shared data ( this is done, because the
Pro*C calls are blocking, and i want the app to continue whatever happens).
The class which i use as shared memory, contains several static members
which can be set and get ( incapsulated by mutexes ). This class also
contains some pointers. These pointers point to memory, allocated by the
mainthread using new operator. The problem is that i get all kinds of
errors, memory faults, segmentation fault even a stack overflow. This errors
occur in the Pro*C calls, but i cannot find the problem. I am afraid the way
memory is shared between threads in NT differs from Unix, but i am not sure.
I also created some Pro*C code using statements as SQL ENABLE THREADS and
use contexes, but it doesnt help, which i guessed because there is only one
thread accessing the database. I compile and link using multithreaded
libraries. Does anybody have a clue of what is going on here ?
Thanks in advance, Jeroen
I worked on a project that did multithreaded statistical modeling. We
used RPC's (via DCE and encina; nowadays corba would be the way to go) to
isolate the multithreaded computational task from the processes doing the
database queries and writes.
No real clues, but a few ideas ...
You mention that your program is multithreaded and that it uses
shared memory. That's a peculiar combination; all the threads of a
multithreaded program share the same address space, so it's not at
all clear why you'd bother setting up shared memory segments.
Perhaps your "multithreaded program" is actually a set of two
or more processes running simultaneously and communicating through
shared memory? If so, keep in mind that the shared memory area may
occupy different addresses in the various processes. This means
that a data object in shared memory will have different addresses
in the various processes; if Process A creates a pointer to such an
object, the pointer value may be meaningless to Process B. If the
objects in shared memory are lists or trees or other multi-part
data structures linked together by pointers, chaos will ensue.
You also mention using "new" to create objects. It's unlikely
that "new" obtains object memory from your shared memory segment;
memory for new objects probably comes from (non-shared) heap space.
If Process A puts a pointer to such an object in shared memory and
Process B tries to use it, B will not have access to the object's
memory and chaos will reign again.
Suggestions:
- If your program consists of multiple threads running in the
context of a single process, don't use shared memory -- it's
just a complication which (as far as I can tell) you don't
need.
- If your program consists of multiple processes communicating
through shared memory, don't try to use pointers to identify
the shared objects. Instead, use something like an int or
long "offset from start of area" or "self-relative offset."
- Objects created by "new" (or by malloc(), for that matter)
almost certainly won't reside in shared memory. There may be
some Alpha-specific magic you can invoke to change this, but
it's more likely that you'll have to write your own code to
handle allocations and deallocations within shared memory.
In addition to Eric's comments, I'd add this as an idea.
Since you have a single thread accessing the database, why are you
using the ORACLE multi-threaded libs? Those are for use when you have
multiple threads accessing ORACLE simultaneously. Since yours is a
multi-thread but only one thread accesses the database, you can just
use normal PRO*C calls and libs and do away with all the complexity of
multi-threaded PRO*C.
As for blocking calls, I thought the latest versions of PRO*C allowed
for non-blocking. If I'm wrong, I know for sure OCI does allow
non-blocking calls. Maybe that could be a better choice? AFAIK, OCI
is available in both UNIX and NT, so portability wouldn't be an issue?
But even OCI won't allow for simultaneous command execution, is that
what you call non-blocking?
Also: depending on the flavour of UNIX, multi-threading may be
achieved in the same address space. Which means you can do away
entirely with shared memory and just use a global heap to pass your
SQL command strings. Much less stuff to go wrong and it would still
work in NT as well.
Just a few ideas, sorry I can't be more specific.
Cheers
Nuno Souto
nso...@bigpond.net.au.nospam
http://www.users.bigpond.net.au/the_Den/index.html
thank for the reactions, Jeroen
"Nuno Souto" <nso...@nsw.bigpond.net.au.nospam> wrote in message
news:3b011672.6007485@news-server...