问题
This question is related to: Is it possible to have several ORB objects in the same process?
So, thanks to @BrianKelly I found information about the ORB
identifier (even though there was no such information in all ORBACUS
docs, that I have) and I successfully created a simple application, that connects to different CORBA
servers and successfully executed several CORBA
requests.
So far, so good.
Now, what I want to do, is to make this application multithreaded and to start a separate thread for the connection to the different servers. But ORB_init
crashes.
Here's a very short code, that I use for testing:
#include <OB/CORBA.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* run( void * );
struct config { const char* nameservice; const char* id; const char* exe; };
const bool mt = true;
int main()
{
config cfg1 = { "NameService=corbaloc::10.102.8.15:13069/NameService", "1", "test" };
config cfg2 = { "NameService=corbaloc::192.168.1.99:13069/NameService", "2", "test" };
if( mt )
{
pthread_t t1, t2;
pthread_create( &t1, NULL, run, (void*)&cfg1 );
pthread_create( &t2, NULL, run, (void*)&cfg2 );
pthread_join( t1, NULL ); pthread_join( t2, NULL );
}
else
{
run( (void*)&cfg1 );
run( (void*)&cfg2 );
}
printf( "SUCCESS!\n" );
return 0;
}
void* run( void* arg )
{
pthread_mutex_lock( &mutex );
int argc = 2; char* argv[3];
config* cfg = (config*)arg;
argv[0] = (char*)cfg->exe;
argv[1] = (char*)cfg->nameservice;
argv[2] = NULL;
CORBA::ORB_var m_varOrb = CORBA::ORB_init( argc, argv, cfg->id );
pthread_mutex_unlock( &mutex );
return NULL;
}
So, when mt
is false
, everything's fine, I can extend the code to create some server specific objects, to execute different requests, etc. But then mt
is true
, the second thread fails calling ORB_init
. See the stack trace below.
I'm pretty sure that I'm missing something very simple and stupid, but what?
$ g++ -g3 -ggdb -Wall -Wshadow -march=i486
-DUNIX -DLINUX -DPTHREADS -DMULTITHREAD -D_REENTRANT
-I. -I/usr/local/include/OB/ -I/usr/local/include/JTC/
-I/usr/include/OB/ -I/usr/include/JTC/ -L/usr/local/lib
-lpthread -lm -lz -lrt -ldl -lOB -lJTC -lCosNaming
test.cpp
Stacktrace:
#0 0x00566402 in __kernel_vsyscall ()
#1 0x0080dfd0 in raise () from /lib/i686/nosegneg/libc.so.6
#2 0x0080f9b1 in abort () from /lib/i686/nosegneg/libc.so.6
#3 0x03dc490b in ~RefCount
(this=Could not find the frame base for "~RefCount".)
at ../../include/OB/RefCount_Ts_Linux-x86-32.h:43
#4 0x03ef8965 in ORBInstance
(this=Could not find the frame base for "ORBInstance".)
at ORBInstance.cpp:276
#5 0x03f134fe in ORB_impl
(this=Could not find the frame base for "ORB_impl".)
at ORB_impl.cpp:281
#6 0x03f24740 in OBCORBA::ORB_init
(ac=Could not find the frame base for
"OBCORBA::ORB_init(int&, char**, OB::Properties*,
OB::Logger*, OB::Reactor*,
char const*, char const*)". )
at ORB_init.cpp:994
#7 0x03f249d9 in CORBA::ORB_init
(ac=Could not find the frame base for
"CORBA::ORB_init(int&, char**, char const*, char const*)".)
at ORB_init.cpp:1014
#8 0x0804895d in run (arg=0xbfe8b544) at test_server.cpp:45
#9 0x007334d2 in start_thread () from /lib/i686/nosegneg/libpthread.so.0
#10 0x008b848e in clone () from /lib/i686/nosegneg/libc.so.6
回答1:
I found something like a workaround. Makes my code really ugly and not easy for support, but it's still something.
Here's what I did:
- add a mechanism (in my application), that will count the necessary threads, before starting them
- read, in advance, the configurations - I need to know the necessary parameters for the naming services (used in
ORB_init
) - before starting any threads, a "manager" will execute just once
ORB_init
, but it will pass several times the-ORBInitRef
parameter, with different values - one for each thread/connection - after this is done, the threads are started, but instead of executing
ORB_init
, they directly executeresolve_initial_references
and continue with the server specific things
Note: My example does not containt resolve_initial_references
, because the crash is in ORB_init
.
So, applying this "algorithm" for this "workaround" would look like:
#include <OB/CORBA.h>
void* run( void * );
CORBA::ORB_var varORB;
int main()
{
/** The necessary configurations */
//-------------------------------------v
const char* nameservice1 = "NameService1=corbaloc::10.102.8.15:13069/NameService";
const char* nameservice2 = "NameService2=corbaloc::192.168.1.99:13069/NameService";
//-------------------------------------^
/** INIT the ORB **/
int argc = 5; char* argv[ 6 ];
const char* initref = "-ORBInitRef";
const char* exe = "test";
argv[0] = (char*)exe;
argv[1] = (char*)initref; argv[2] = (char*)nameservice1;
argv[3] = (char*)initref; argv[4] = (char*)nameservice2;
argv[5] = NULL;
varORB = CORBA::ORB_init( argc, argv );
pthread_t t1, t2;
char ns_id1 = '1', ns_id2 = '2';
pthread_create( &t1, NULL, run, (void*)&ns_id1 );
pthread_create( &t2, NULL, run, (void*)&ns_id2 );
pthread_join( t1, NULL ); pthread_join( t2, NULL );
varORB->destroy();
return 0;
}
void* run( void* arg )
{
char nameservice[] = "NameServiceN";
// set the right number of the nameservice
nameservice[ 11 ] = *((char*)arg);
varORB->resolve_initial_references( nameservice );
// do some CORBA-specific stuff
printf( "SUCCESS %c\n", *(char*)arg );
return NULL;
}
NOTE
I still can't believe this is the only option. If you look at my code (in the question) carefully, you'll see, that:
- it IS possible to have multiple ORBs (see the case with
mt == false
) - the call to
ORB_init
IS synchronized - the ORB identifier IS implemented and it works fine (again with
mt == false
)
So, this is not actual answer to my question, it's kind of a workaround.
It doesn't make sense (at least to me) to be possible to create several ORBs in a single thread, but not in multiple threads.
回答2:
The ORB will use different connections (and threads) to different servers every time - always. Receiving answers and incomming calls are also handled in different threads (if useful and/or needed).
I think you try try to solve things, that the ORB already has solved for you. It's a middleware, don't scare about threading and stuff. It's already done by CORBA experts.
来源:https://stackoverflow.com/questions/13009694/use-multiple-orbs-through-different-threads-multithreaded-multi-orb-client-appl