通过不同的线程使用多个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; }
所以,当mt
为false
,一切都很好,我可以扩展代码来创建一些服务器特定的对象,执行不同的请求等等。但是mt
是true
,第二个线程无法调用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专家完成。