通过使用不同的线程多的ORB(多线程多宝珠客户端应用程序) - 怎么样? [英] Use multiple ORBs through different threads (multithreaded multi-orb client application) - how?

查看:195
本文介绍了通过使用不同的线程多的ORB(多线程多宝珠客户端应用程序) - 怎么样?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<子>这个问题涉及到:<一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 execute resolve_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆