我在多线程环境下使用MQSeries Perl模块时遇到了问题。以下是我尝试过的方法:
- 在不同的线程中使用
$mqMgr = MQSeries::QueueManager->new()
创建两个句柄。我以为这会给我两个连接到MQ,但实际上第二次调用MQOPEN()
返回码为2219,这可能意味着我从两个单独的调用new()方法中得到了相同的底层连接。 - 只声明一个$mqMgr作为全局共享变量。但我无法将MQSeries::QueueManager对象的引用分配给
$mqMgr
。原因是:"传递给threads::shared::share的参数1的类型必须是[$@%]之一(而不是子例程条目)" - 只声明一个
$mqMgr
作为全局变量。仍然得到相同的2219代码。 - 尝试将
MQCNO_HANDLE_SHARE_NO_BLOCK
传递到MQSeries::QueueManager->new()
中,以便可以在线程间共享单个连接。但我找不到一种方法来传递它。
我的问题是,使用Perl模块MQSeries:
- 如何/能否从不同的线程获取到与MQ队列管理器的单独连接?
- 如何/能否在不同的线程之间共享与MQ队列管理器的连接?
我已经搜索过,但运气不佳,任何信息将不胜感激。
相关问题:
更新1:添加一个例子,即在两个线程中使用两个本地的MQSeries :: QueueManager对象会导致MQ错误代码2219。
use threads;
use Thread::Queue;
use MQSeries;
use MQSeries::QueueManager;
use MQSeries::Queue;
# globals
our $jobQ = Thread::Queue->new();
our $resultQ = Thread::Queue->new();
# ----------------------------------------------------------------------------
# sub routines
# ----------------------------------------------------------------------------
sub worker {
# fetch work from $jobQ and put result to $resultQ
# ...
}
sub monitor {
# fetch result from $resultQ and put it onto another MQ queue
my $mqQMgr = MQSeries::QueueManager->new( ... );
# different queue from the one in main
# this would cause error with MQ code 2219
my $mqQ = MQSeries::Queue->new( ... );
while (defined(my $result = $resultQ->dequeue())) {
# create an mq message and put it into $mqQ
my $mqMsg = MQSeries::Message->new();
$mqQ->put($mqMsg);
}
}
# main
unless (caller()) {
# create connection to MQ
my $mqQMgr = MQSeries::QueueManager->new( ... );
my $mqQ = MQSeries::Queue->new( ... );
# create worker and monitor thread
my @workers;
for (1 .. $nThreads) {
push(@workers, threads->create('worker'));
}
my $monitor = threads->create('monitor');
while (True) {
my $mqMsg = MQSeries::Message->new ();
my $retCode = $mqQ->get(
Message => $mqMsg,
GetMsgOptions => $someOption,
Wait => $sometime
);
die("error") if ($retCode == 0);
next if ($retCode == -1); # no message
# not we have some job to do
$jobQ->enqueue($mqMsg->Data);
}
}