通过不同的线程(多线程多孔客户端应用程序)使用多个球体
Use multiple ORBs through different threads (multithreaded multi-orb client application) - how?
这个问题与:有可能在同一过程中具有多个ORB对象?
因此,感谢@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;
}
因此,当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
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
我找到了类似于解决方法的东西。使我的代码真的很丑陋,并且并不容易支持,但仍然是什么。
这是我所做的:
- 添加一个机制(在我的应用程序中),该机制将在启动之前计算必要的线程
- 预先阅读配置 - 我需要知道命名服务的必要参数(
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 %cn", *(char*)arg );
return NULL;
}
注意
我仍然不敢相信这是唯一的选择。如果您仔细查看我的代码(在问题中),您会看到:
- 是有多个球(请参阅
mt == false
的情况) - 呼叫
ORB_init
是同步 - ORB标识符 IS 已实现,它可以正常工作(再次使用
mt == false
)
所以,这不是我问题的实际答案,这是一种解决方法。
在单个线程中创建多个球体而不是在多个线程中创建多个球体是没有意义的(至少对我来说)。
球每次都将使用不同的连接(和线程)对不同的服务器使用不同的连接(和线程)。接收答案和不断呼叫的呼叫也将在不同的线程中处理(如果有用和/或需要)。
我想您尝试解决问题,Orb已经为您解决了问题。这是中间件,不要吓到线程和东西。它已经由Corba专家完成。
- 使用调试/崩溃报告将应用程序部署到客户端
- 在 1 个服务器 n 客户端套接字 C++ MFC 应用程序中更新数据的客户端
- C++库和自注册类:客户端应用程序中的工厂映射为空
- OpenGL GLFW 应用程序 - 客户端内存限制
- CMake导出的库-在客户端应用程序中找不到include/Lib路径
- 我的web应用程序的用户需要在浏览器上手动启用本机客户端吗
- C++启动另一个程序(客户端-服务器)的程序
- 我正在编写一个简单的客户端套接字应用程序,但在连接后服务器收到一个空缓冲区
- C++客户端/服务器聊天应用程序 - 从 Ubuntu 命令窗口扫描输入
- 必须在客户端计算机上安装的内容才能运行QT快速应用程序
- GDB执行时,Apache IGNITE C 客户端应用程序具有许多细分故障
- 多连接客户端套接字应用程序C++
- 如何将OpenCV的输出显示或流式传输到HTML页面或其他一些客户端应用程序
- 将C 代码(本机客户端)移植到浏览器(Web应用程序)
- 如果您不编写 Web 应用程序,并且您的客户端不是浏览器,那么 Web 套接字相对于常规套接字的优势是什么?
- 从 SharePoint 2010 服务器下载,在 Windows 客户端上的本地应用程序中打开
- 使用qt的多客户端/服务器TCP应用程序
- 如何在Qt客户端应用程序中显示我的OSM磁贴
- 在DLL中分配内存并将其指针提供给客户端应用程序,这是不是一种糟糕的做法
- -客户端-服务器应用程序-服务器端的recv()可以正常工作,但客户端的recv()会阻塞程序