通过不同的线程使用多个 ORB(多线程多 ORB 客户端应用程序) - 如何?
Posted
技术标签:
【中文标题】通过不同的线程使用多个 ORB(多线程多 ORB 客户端应用程序) - 如何?【英文标题】:Use multiple ORBs through different threads (multithreaded multi-orb client application) - how? 【发布时间】:2012-10-22 10:40:31 【问题描述】:本题涉及:Is it possible to have several ORB objects in the same process?
所以,感谢@BrianKelly,我找到了有关ORB
标识符的信息(尽管我拥有的所有ORBACUS
文档中都没有此类信息)并且我成功创建了一个简单的应用程序,它连接到不同的@ 987654325@ 服务器并成功执行了多个CORBA
请求。
到目前为止,一切都很好。
现在,我想做的是让这个应用程序成为多线程的,并启动一个单独的线程来连接到不同的服务器。但是ORB_init
崩溃了。
这是一个非常短的代码,我用于测试:
#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;
所以,当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
【问题讨论】:
在你的线程函数结束时尝试调用m_varOrb->shutdown(true)
,然后调用m_VarOrb->destroy()
。这样,ORB 将在 _var
超出范围并清理它所指向的内容之前被清理。
您可能还想在这里阅读 Ciaran McHale 的 CORBA 优秀指南:ciaranmchale.com/corba-explained-simply
@BrianKelly - 好吧,这是一个小例子,重现了我的问题,而不是真实的代码。实际上,run
函数是一个类的成员,派生线程的类包装器,内部有一个while( m_bRunning )
循环,所有线程(通常是 4 个)应该能够同时工作。因此,在 run
的末尾执行 shutdown
和 destroy
不是选项(它们是在 DoDisconnect
方法中执行的,但这是另一回事。
@KirilKirov “但这意味着(目前) - 只有一台服务器”是什么意思。 - 您不需要多个 ORB 实例。这没有意义。请更详细地描述您的实际问题。我觉得您认为多个 ORB 可以解决您的问题,但可能不会。
@KirilKirov ORB 每次都会使用不同的连接(和线程)到不同的服务器 - 总是。接收答案和来电也在不同的线程中处理。我认为您尝试尝试解决 ORB 已经为您解决的问题。这是一个中间件,不要害怕线程和东西。 CORBA 专家已经完成了这项工作。
【参考方案1】:
我找到了类似的解决方法。让我的代码真的很丑,而且不容易支持,但它仍然是一些东西。
这就是我所做的:
添加一个机制(在我的应用程序中),在启动之前计算必要的线程数 提前阅读配置 - 我需要知道命名服务的必要参数(用于ORB_init
)
在启动任何线程之前,“管理器”将执行一次 ORB_init
,但它会传递数次 次-ORBInitRef
参数,具有不同的值 -每个线程/连接一个
完成后,线程启动,但不是执行ORB_init
,而是直接执行resolve_initial_references
并继续执行服务器特定的事情
注意:我的示例不包含resolve_initial_references
,因为崩溃在ORB_init
。
因此,将此“算法”应用于此“解决方法”如下所示:
#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;
注意
我仍然不敢相信这是唯一的选择。如果您仔细查看我的代码(在问题中),您会发现:
IS可能有多个 ORB(参见mt == false
的案例)
对ORB_init
的调用IS同步
ORB 标识符 IS 已实现并且工作正常(再次使用 mt == false
)
所以,这不是我的问题的实际答案,它是一种解决方法。
在单个线程中创建多个 ORB 是没有意义的(至少对我而言),但在多个线程中却不行。
【讨论】:
如果我真的有理由多次调用 ORB_init(),我会这样做。 :) 例如,omniORB 假设有关调用 ORB_init() 的线程的某些事情,因此用另一个线程再次调用它可能会混淆它。我怀疑你的 ORB 也是如此。 噗,失败!即使ORB
对象是shutdown
和destroy
-ed,也不能被其他线程创建! 只能由第一个线程再次初始化它,该线程在一开始就调用了ORB_init
。这是荒谬的!如果我尝试从另一个线程初始化它(在它被销毁之后),崩溃是一样的。我真的不敢相信,该死的。
我仍然不确定您为什么要多次调用 ORB_init。是因为您需要联系不同的命名服务吗?我不确定,但我认为您应该能够初始化 orb 一次,然后使用 orb.string_to_object() 使用每个命名服务的某种 URI 创建对每个命名服务的对象引用。【参考方案2】:
ORB 每次都会使用不同的连接(和线程)到不同的服务器 - 总是如此。接收答案和来电也在不同的线程中处理(如果有用和/或需要)。
我认为您尝试尝试解决 ORB 已经为您解决的问题。这是一个中间件,不要害怕线程和东西。 CORBA 专家已经完成了这项工作。
【讨论】:
好的,关于整个应用程序的更多信息 - 我有一个线程,它接受来自另一个应用程序的请求(不是 CORBA)。该线程分析这些请求并决定如何处理它们。这些请求必须重新路由到 一个 几个不同的 CORBA 服务器。换句话说,这个线程是一种管理器,它管理多个线程,连接到不同的 CORBA 服务器。这就是为什么我需要有不同的线程,它们在单个应用程序中处理与不同 CORBA 服务器的不同连接。 这是一个包含 25 000 多行代码的应用程序架构,适用于不同的协议(超过 20 种)。这里,CORBA 部分是协议特定部分。这是应用程序使用的连接器架构,它必须能够使用任何协议与任何其他应用程序进行通信。我的意思是——我不能改变架构。 是的,我明白了。我只是在解释我要做什么以及为什么要做。 我会给你赏金,因为它们很快就会到期并且因为你的努力。谢谢,这是有用的信息,但实际上并不能回答我的问题。 很抱歉,它不符合您的问题,也不是您期望得到的。以上是关于通过不同的线程使用多个 ORB(多线程多 ORB 客户端应用程序) - 如何?的主要内容,如果未能解决你的问题,请参考以下文章
ORB-SLAM2 论文&代码学习 —— Tracking 线程