加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl:IPC :: Shareable和SWIG’ed C对象不同意

发布时间:2020-12-15 23:34:34 所属栏目:大数据 来源:网络整理
导读:对于我的某个Perl项目,我需要几个Perl进程来共享一些位于C库中的资源. (不要问,这不是这个问题的核心,只是背景.) 因此,我试图在这个上下文中钻研两个“新”字段: IPC::Shareable ,并使用SWIG包装C.看来我在那里做错了,这就是我想问的问题. 在C方面,我写了一
对于我的某个Perl项目,我需要几个Perl进程来共享一些位于C库中的资源. (不要问,这不是这个问题的核心,只是背景.)

因此,我试图在这个上下文中钻研两个“新”字段:IPC::Shareable,并使用SWIG包装C.看来我在那里做错了,这就是我想问的问题.

在C方面,我写了一个小测试类Rectangle,它带有一个空构造函数,一个set和一个size成员函数.

然后我将该类包装在SWIG生成的Perl包示例中.

在Perl方面,我试过SWIG模块按预期工作:

use example;
my $testrec = new example::Rectangle;
$testrec->set( 6,7 );
print $testrec->size() . "n";

这样打印“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,'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;
}

客户端”:

use IPC::Shareable;
use example;

# v_ for variable,g_ for (IPC) glue

my $v_array;
my $v_rect;

my %options = ( create => 0,destroy => 0 );

tie $v_array,{ %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;
}

首先启动“服务器”,然后是“客户端”,我得到“服务器”的输出:

server array: 0
server rect:  42
server array: 0 - 1
server rect:  42
server array: 0 - 1 - 2
server rect:  42

而这个输出为“客户端”:

client array: 0
client rect:  0
client array: 0 - 1
client rect:  3
client array: 0 - 1 - 2
client rect:  6

显然,数组引用可以共享,但是客户端没有“看到”服务器的示例:: Rectangle,而是在一个(零初始化的)流氓内存上工作,反过来服务器一无所知…

我怀疑我必须为$v_rect做些什么来使这项工作正常,但我在OO Perl中不够坚实,不知道是什么.谁来救援?

解决方法

你想做什么是行不通的.你将不得不咬紧牙关并做一些形式的消息传递.

我不太清楚SWIG如何为Perl包装C()级别的对象,但它很可能是通常的,无可否认的“整数槽指针”策略.在此设置中,它将分配一个C()对象并在Perl标量中存储指向它的指针. Perl对象将成为这个标量的祝福参考.当对Perl对象的所有引用都消失时,Perl类的析构函数将显式释放C()对象.更现代的技术就像XS :: Object :: Magic模块允许你做的那样.

但是包装器的细节甚至都不重要.重要的是该对象对Perl是不透明的!通过联系,IPC :: Shareable无论如何都使用了一些时尚和坦率的脆弱技术.它可能适用于您的Perl对象,也可能不适用.但是当您共享Perl对象时,将不会共享C()对象.怎么可能呢? Perl对此一无所知.它不可能.

你应该做的是在消息传递和序列化方面考虑问题.为了序列化你的C()对象,你需要允许来自C方面的一些合作.看看Storable模块为序列化对象提供的钩子.就消息传递/排队而言,我很高兴使用ZeroMQ,它为您提供了一个简单的类似套接字的接口.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读