0

この質問は次のことに関連しています。同じプロセスに複数のORBオブジェクトを含めることは可能ですか?

そのため、@ BrianKellyのおかげで、識別子に関する情報を見つけ(すべてのドキュメントにそのORBような情報はありませんでしたが)、さまざまなサーバーに接続していくつかのリクエストを正常に実行する単純なアプリケーションを正常に作成しました。ORBACUSCORBACORBA

ここまでは順調ですね。

ここで、私がやりたいのは、このアプリケーションをマルチスレッド化し、異なるサーバーへの接続用に別のスレッドを開始することです。しかし、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;
}

したがって、mtfalse、すべてが正常である場合、コードを拡張してサーバー固有のオブジェクトを作成したり、さまざまな要求を実行したりできます。しかし、そうすると、2番目のスレッドはの呼び出しに失敗しmtます。以下のスタックトレースを参照してください。trueORB_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
4

2 に答える 2

0

ORBは、常に異なるサーバーへの異なる接続(およびスレッド)を使用します。応答の受信と着信呼び出しも、異なるスレッドで処理されます(有用および/または必要な場合)。

ORBがすでに解決していることを解決しようとしていると思います。これはミドルウェアです。スレッド化などを恐れないでください。これは、CORBAの専門家によってすでに行われています。

于 2012-10-30T15:07:06.953 に答える
0

回避策のようなものを見つけました。私のコードは本当に醜く、サポートが簡単ではありませんが、それでも何かです。

これが私がしたことです:

  • 必要なスレッドを開始する前にカウントするメカニズムを(私のアプリケーションに)追加します
  • 事前に構成を読んでください-ネーミングサービスに必要なパラメータを知る必要があります(で使用されていますORB_init
  • スレッドを開始する前に、「マネージャー」は1回だけ実行されますが、パラメーターが ORB_init渡され、値が異なります(スレッド/接続ごとに1つ)。-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;
}

ノート

これが唯一の選択肢だとはまだ信じられません。(質問の)私のコードを注意深く見ると、次のことがわかります。

  • 複数のORBを持つことが可能です(の場合参照mt == false
  • ORB_init IS同期への呼び出し
  • ORB識別子が実装されており、正常に機能します(これもmt == false

したがって、これは私の質問に対する実際の答えではなく、一種の回避策です。

単一のスレッドで複数のORBを作成できることは(少なくとも私には)意味がありませんが、複数のスレッドで作成することはできません。

于 2012-10-26T14:42:04.990 に答える