通过不同的线程使用多个ORB(multithreading多orb客户端应用程序) – 如何?

这个问题与以下内容有关: 是否可以在同一个进程中拥有多个ORB对象?

所以,多亏了@BrianKelly,我找到了有关ORB标识符的信息(即使在我所有的ORBACUS文档中都没有这样的信息),我成功创建了一个简单的应用程序,它连接到不同的CORBA服务器并成功执行了几个CORBA请求。

到现在为止还挺好。

现在,我想要做的是使这个应用程序multithreading并启动一个单独的线程来连接到不同的服务器。 但是ORB_init崩溃了。

这是一个非常短的代码,我用于测试:

 #include  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; } 

所以,当mtfalse ,一切都很好,我可以扩展代码来创建一些服务器特定的对象,执行不同的请求等等。但是mttrue ,第二个线程无法调用ORB_init 。 请参阅下面的堆栈跟踪。

我很确定我错过了一些非常简单和愚蠢的东西,但是什么呢?

 $ 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 

堆栈跟踪:

 #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 

我找到了类似解决方法的东西。 使我的代码非常丑陋并且不容易获得支持,但它仍然是一些东西。

这是我做的:

  • 添加一个机制(在我的应用程序中),它将在启动它们之前计算必要的线程
  • 提前读取配置 – 我需要知道命名服务的必要参数(在ORB_init
  • 在启动任何线程之前,“manager”将执行一次 ORB_init ,但它将传递-ORBInitRef参数的几次 ,具有不同的值 – 每个线程/连接一个
  • 完成此操作后,线程将启动,但不是执行ORB_init ,而是直接执行resolve_initial_references并继续执行特定于服务器的事情

注意:我的示例不包含resolve_initial_references ,因为崩溃在ORB_init


因此,对此“解决方法”应用此“算法”将如下所示:

 #include  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; } 

注意

我仍然无法相信这是唯一的选择。 如果仔细查看我的代码(在问题中),你会看到:

  • 可以有多个ORB(参见mt == false的情况)
  • ORB_init的调用同步的
  • ORB标识符已实现且工作正常(同样使用mt == false

所以,这不是我的问题的实际答案,它是一种解决方法。

在单个线程中创建多个ORB但在多个线程中不能创建多个ORB是没有意义的(至少对我而言)。

ORB每次都会使用不同的连接(和线程)到不同的服务器 – 总是如此。 接收答案和接收呼叫也在不同的线程中处理(如果有用和/或需要)。

我想你试着尝试解决问题,ORB已经为你解决了。 它是一个中间件,不要吓唬线程和东西。 它已经由CORBA专家完成。