通过使用不同的线程多的ORB(多线程多宝珠客户端应用程序) - 怎么样? [英] Use multiple ORBs through different threads (multithreaded multi-orb client application) - how?
问题描述
<子>这个问题涉及到:<一href=\"http://stackoverflow.com/questions/12933790/is-it-possible-to-have-several-orb-objects-in-the-same-process\">Is有可能有在同一过程中的几个ORB对象?
所以,感谢@BrianKelly我发现有关 ORB
标识符(即使是在完全没有这样的信息资料的Orbacus
文档,我有),我成功地创建了一个简单的应用程序,连接到不同的 CORBA
服务器,并成功地执行了几个 CORBA
请求。
到目前为止,一切都很好。
现在,我想做的事,就是让这个应用程序的多线程,并启动一个单独的线程用于连接到不同的服务器。但 ORB_init
崩溃。
下面是一个很短的code,我使用的测试:
的#include&LT; OB / CORBA.h&GT;pthread_mutex_t互斥= PTHREAD_MUTEX_INITIALIZER;
void *的运行(无效*);结构配置{为const char *名称服务;为const char * ID;为const char * exe文件; };常量布尔MT = TRUE;诠释的main()
{
配置CFG1 = {名称服务= corbaloc :: 10.102.8.15:13069 /名称服务,1,测试};
配置CFG2 = {名称服务= corbaloc :: 192.168.1.99:13069 /名称服务,2,测试}; 如果(MT)
{
的pthread_t T1,T2; 在pthread_create(安培; T1,NULL,运行,(无效*)及CFG1);
在pthread_create(安培; t2时,空,运行,(无效*)及CFG2); 在pthread_join(T1,NULL);在pthread_join(T2,NULL);
}
其他
{
运行((无效*)及CFG1);
运行((无效*)及CFG2);
} 的printf(成功\\ n!);
返回0;
}void *的运行(无效* ARG)
{
调用pthread_mutex_lock(安培;互斥); INT ARGC = 2;的char * argv的[3]; 配置* CFG =(配置*)ARG;
的argv [0] =(字符*)CFG-&GT; exe文件;
ARGV [1] =(字符*)CFG-&GT;名称服务;
的argv [2] = NULL; CORBA :: ORB_var m_varOrb = CORBA :: ORB_init(ARGC,ARGV,CFG-&GT; ID); 调用pthread_mutex_unlock(安培;互斥);
返回NULL;
}
所以,当 MT
是假
,一切都很好,我可以延长code创建一些服务器的特定对象,执行不同的要求,等等。但随后 MT
是真正
,第二个线程调用失败 ORB_init
。请参阅下面的堆栈跟踪。
我是pretty肯定,我失去了一些东西很简单,愚蠢的,但什么?
$ G ++ -g3 -ggdb -Wall -Wshadow -march = i486的
-DUNIX -DLINUX -DPTHREADS -DMULTITHREAD -D_REENTRANT
-一世。 -I在/ usr /本地/包括/ OB / -I在/ usr /本地/包括/ 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在__kernel_vsyscall()
从/lib/i686/nosegneg/libc.so.6#1 0x0080dfd0在加薪()
#2 0x0080f9b1在中止()从/lib/i686/nosegneg/libc.so.6
#3 0x03dc490b在〜引用计数
(此=无法找到〜引用计数的框架基础。)
在../../include/OB/RefCount_Ts_Linux-x86-32.h:43
#4 0x03ef8965在ORBInstance
(此=找不到ORBInstance框架的基础。)
在ORBInstance.cpp:276
#5 0x03f134fe在ORB_impl
(此=找不到ORB_impl框架的基础。)
在ORB_impl.cpp:281
#6 0x03f24740在OBCORBA :: ORB_init
(AC =找不到框架基
OBCORBA :: ORB_init(INT和放大器;,字符**,OB ::属性*
OB ::记录器*,OB ::反应堆*
字符常量*,字符常量*)。)
在ORB_init.cpp:994
#7 0x03f249d9在CORBA :: ORB_init
(AC =找不到框架基
CORBA :: ORB_init(INT和放大器;,字符**,字符常量*,字符常量*)。)
在ORB_init.cpp:1014
#8 0x0804895d在test_server.cpp运行(ARG = 0xbfe8b544):45
#9 0x007334d2在start_thread()从/lib/i686/nosegneg/libpthread.so.0
从/lib/i686/nosegneg/libc.so.6#10 0x008b848e在克隆()
我发现有点像一个解决方法。让我的code真难看,不容易获得支持,但它仍然是东西。
下面是我所做的:
- 开始之前增加一个机构(在我的应用程序),就会计算所需的线程,
- 阅读,提前配置 - 我需要知道的命名服务所需的参数(中使用
ORB_init
) - 启动任何线程,一个经理之前将执行只有一次
ORB_init
,但它会通过的几种次-ORBInitRef
参数,使用不同的值 - 每个线程/连接 - 这样做了之后,线程启动,但不是执行
ORB_init
,他们直接执行的resolve_initial_references
和继续服务器具体的事情
请注意:我的例子不containt 的resolve_initial_references
,因为崩溃发生在 ORB_init
所以,采用这种算法对于这种解决办法看起来像:
的#include&LT; OB / CORBA.h&GT;void *的运行(无效*);
CORBA :: ORB_var varORB;诠释的main()
{
/ **必要的配置* /
// ------------------------------------- v
为const char * nameservice1 =NameService1 = corbaloc :: 10.102.8.15:13069 /名称服务;
为const char * nameservice2 =NameService2 = corbaloc :: 192.168.1.99:13069 /名称服务;
// ------------------------------------- ^ / ** INIT ORB的** /
INT ARGC = 5;的char * argv的[6];
为const char * initref =-ORBInitRef;
为const char * exe文件=测试; 的argv [0] =(字符*)exe文件;
ARGV [1] =(字符*)initref;的argv [2] =(字符*)nameservice1;
的argv [3] =(字符*)initref;的argv [4] =(字符*)nameservice2;
的argv [5] = NULL; varORB = CORBA :: ORB_init(ARGC,ARGV); 的pthread_t T1,T2; 炭ns_id1 ='1',ns_id2 ='2';
在pthread_create(安培; T1,NULL,运行,(无效*)及ns_id1);
在pthread_create(安培; t2时,空,运行,(无效*)及ns_id2); 在pthread_join(T1,NULL);在pthread_join(T2,NULL); varORB-&GT;的destroy(); 返回0;
}
void *的运行(无效* ARG)
{
字符名称服务[] =NameServiceN; //设置名称服务的正确数量
名称服务[11] = *((字符*)ARG); varORB-&GT;的resolve_initial_references(名称服务); //做一些具体的CORBA的东西 的printf(SUCCESS%C \\ n,*(字符*)ARG);
返回NULL;
}
注意
我仍然无法相信这是唯一的选择。如果你看看我的code(在这个问题)仔细,你会看到,那:
- 它的是可能有多个ORB上(请参阅使用
MT的情况下==虚假
) - 调用
ORB_init
是同步 - 的ORB标识符的是实施和正常工作(再次与
MT ==虚假
)
所以,这是不现实的回答我的问题,它是一种变通方法的。
这是没有意义的(至少我)是有可能在一个单独的线程创建多个ORB的,但不是在多个线程。
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
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.
这篇关于通过使用不同的线程多的ORB(多线程多宝珠客户端应用程序) - 怎么样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!