gpt4 book ai didi

c++ - 通过不同的线程使用多个 ORB(多线程多 Orb 客户端应用程序) - 如何?

转载 作者:行者123 更新时间:2023-11-30 17:57:05 24 4
gpt4 key购买 nike

此问题涉及:Is it possible to have several ORB objects in the same process?

所以,多亏了@BrianKelly,我找到了有关 ORB 标识符的信息(尽管我拥有的所有 ORBACUS 文档中都没有此类信息),并且我成功了创建了一个简单的应用程序,该应用程序连接到不同的 CORBA 服务器并成功执行了多个 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;
}

所以,当mtfalse时,一切都很好,我可以扩展代码来创建一些服务器特定的对象,执行不同的请求等。但是mttrue,第二个线程调用 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 中使用)
  • 在启动任何线程之前,“管理器”将仅执行一次 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;
}
<小时/>

注意

我仍然不敢相信这是唯一的选择。如果您仔细查看我的代码(在问题中),您会发现:

  • 可以有多个 ORB(参见 mt == false 的案例)
  • 调用ORB_init 已同步
  • ORB 标识符IS已实现并且工作正常(再次使用 mt == false )

所以,这并不是我问题的实际答案,而是一种解决方法。

在单个线程中创建多个 ORB 是没有意义的(至少对我来说),但在多个线程中则不行。

关于c++ - 通过不同的线程使用多个 ORB(多线程多 Orb 客户端应用程序) - 如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13009694/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com