对于我的某个Perl项目,我需要几个Perl进程来共享一些位于C++库中的资源.(不要问,这不是这个问题的核心,只是背景.)
因此,我试图在这个上下文中钻研两个"新"字段:IPC::Shareable并使用SWIG包装C++.看来我在那里做错了,这就是我想问的问题.
在C++方面,我Rectangle用一个空构造函数,set一个size成员函数编写了一个小测试类.
然后我将该类包装在SWIG生成的Perl包中example.
在Perl方面,我试过SWIG模块按预期工作:
use example;
my $testrec = new example::Rectangle;
$testrec->set( 6, 7 );
print $testrec->size() . "\n";
Run Code Online (Sandbox Code Playgroud)
这样打印"42".
然后我试着测试我的使用方式IPC::Shareable.我编写了两个Perl脚本,一个"服务器"和一个"客户端"来测试资源共享.
服务器":
use IPC::Shareable;
use example;
# v_ for variable, g_ for (IPC) glue
my $v_array;
my $v_rect;
my %options = ( create => 'yes', exclusive => 0, mode => 0644, destroy => 'yes' );
tie $v_array, 'IPC::Shareable', 'g_array', { %options } or die;
tie $v_rect, 'IPC::Shareable', 'g_rect', { %options } or die;
$v_array = [ "0" ];
$v_rect = new example::Rectangle;
$v_rect->set( 6, 7 );
while ( 1 ) {
print "server array: " . join( " - ", @$v_array ) . "\n";
print "server rect: " . $v_rect->size() . "\n";
sleep 3;
}
Run Code Online (Sandbox Code Playgroud)
客户端":
use IPC::Shareable;
use example;
# v_ for variable, g_ for (IPC) glue
my $v_array;
my $v_rect;
my %options = ( create => 0, exclusive => 0, mode => 0644, destroy => 0 );
tie $v_array, 'IPC::Shareable', 'g_array', { %options } or die;
tie $v_rect, 'IPC::Shareable', 'g_rect', { %options } or die;
my $count = 0;
while ( 1 ) {
print "client array: " . join( " - ", @$v_array ) . "\n";
print "client rect: " . $v_rect->size() . "\n";
push( @$v_array, ++$count );
$v_rect->set( 3, $count );
sleep 3;
}
Run Code Online (Sandbox Code Playgroud)
首先启动"服务器",然后是"客户端",我得到"服务器"的输出:
server array: 0
server rect: 42
server array: 0 - 1
server rect: 42
server array: 0 - 1 - 2
server rect: 42
Run Code Online (Sandbox Code Playgroud)
而这个输出为"客户端":
client array: 0
client rect: 0
client array: 0 - 1
client rect: 3
client array: 0 - 1 - 2
client rect: 6
Run Code Online (Sandbox Code Playgroud)
显然,数组引用可以共享,但是客户端没有"看到"服务器的示例:: Rectangle,而是在一个(零初始化的)流氓内存上工作,反过来服务器一无所知...
我怀疑我必须做些什么来$v_rect使这项工作正常,但我在OO Perl中不够坚实,不知道是什么.谁来救援?
你想做的事是行不通的。您将不得不硬着头皮进行某种形式的消息传递。
我不太记得 SWIG 是如何准确地包装 Perl 的 C(++) 级对象,但它很可能是常见的、不可否认的可怕的“整数槽中的指针”策略。在此设置中,它将分配一个 C(++) 对象并将指向它的指针存储在 Perl 标量中。Perl 对象将是对此标量的祝福引用。当对 Perl 对象的所有引用都消失时,C(++) 对象将由 Perl 类的析构函数显式释放。更现代的技术类似于 XS::Object::Magic 模块允许您执行的操作。
但包装的细节并不那么重要。重要的是该对象对于 Perl 来说是不透明的!就关系而言,IPC::Shareable 无论如何都使用了一些过时且坦率地说脆弱的技术。它可能适用于您的 Perl 对象,也可能不适用于您的 Perl 对象。但是当你共享 Perl 对象时,C(++) 对象将不会被共享。怎么可能呢?Perl对此一无所知。而且这不可能。
相反,您应该做的是考虑消息传递和序列化方面的问题。为了序列化您的 C(++) 对象,您需要允许 C 方面的一些合作。看一下 Storable 模块提供的用于序列化对象的钩子。就消息传递/队列而言,我很喜欢使用 ZeroMQ,它为您提供了一个简单的类似套接字的接口。
| 归档时间: |
|
| 查看次数: |
288 次 |
| 最近记录: |