gpt4 book ai didi

linux - 不使用共享内存的 Perl IPC?

转载 作者:太空狗 更新时间:2023-10-29 11:46:49 25 4
gpt4 key购买 nike

部分代码为:

sub _getPages {
my $self = shift;
my $rel_url = lc(shift);
my @turls = ();
my $urls = [];
my $ipc_share = tie $urls, 'IPC::Shareable',undef, { destroy => 1 };

foreach my $stag (@{$self->{SUPP_TAGS}}) {

push(@{$urls}, map { lc($self->_normalizeSupportURL($_->url(),
$self->{MECH_O}->getGlobalMechInstance()->uri->authority,
$self->{MECH_O}->getGlobalMechInstance()->uri->scheme)) }
grep { ((index($_->url,$rel_url) > -1) || ($_->url =~ m{^/})) &&
$_->url !~ m/answer|mailto:/i }
$self->{MECH_O}->getGlobalMechInstance()->find_all_links( text_regex => qr/$stag/i ),
$self->{MECH_O}->getGlobalMechInstance()->find_all_links( name_regex => qr/$stag/i ),
$self->{MECH_O}->getGlobalMechInstance()->find_all_links( url_abs_regex => qr/$stag/i ));
}
@{$urls} = uniq(@{$urls});

foreach my $url (@{$urls}) {

if (!exists($self->{UNQ_URLS}->{lc($url)})) {
$self->{UNQ_URLS}->{lc($url)} = 1;

$self->{SUPP_PROC}->start and next;
if (eval {$self->{MECH_O}->getGlobalMechInstance()->get($url); } ) {
push(@{$urls}, map { lc($self->_normalizeSupportURL($_->url(),
$self->{MECH_O}->getGlobalMechInstance()->uri->authority,
$self->{MECH_O}->getGlobalMechInstance()->uri->scheme)) }
grep { ((index($_->url,$rel_url) > -1) || ($_->url =~ m{^/}) ||
$_->url =~ m/\d+\.\d+\.\d+\.\d+/ ) &&
$_->url !~ m/answer|mailto:/i }
$self->{MECH_O}->getGlobalMechInstance()->find_all_links( text_regex => qr/chat/i ),
$self->{MECH_O}->getGlobalMechInstance()->find_all_links( name_regex => qr/chat/i ),
$self->{MECH_O}->getGlobalMechInstance()->find_all_links( url_abs_regex => qr/chat/i ));
}
$self->{SUPP_PROC}->finish;
}
}
$self->{SUPP_PROC}->wait_all_children;

return uniq(@{$urls});
}

基本上,我想做的是在进程之间共享 $urls,这样我就可以向它添加 url,但我不断收到:

Could not create semaphore set: No space left on device

这是做内核(Ubuntu 10.04 LTS)参数(SEMMNI,SEMMNS)的事情。我增加了它们,但它仍然没有真正用处,所以我可能在这里做错了什么。

还有另一种方式(可能是 Storable 相关解决方案...)在进程之间共享数组吗?

谢谢,

最佳答案

您可能已经这样做了,但最好确认到底是什么失败了,以及您所做的更改是否生效。要确认这确实是 semget() 返回 ENOSPC,您可以运行它:

strace -ooutfile 命令

然后在 outfile 中查找 ENOSPC 以确认哪个系统调用返回了它。

要确认调整 SEMMNI 和 SEMMNS 是否有效,您可以:

cat/proc/sys/kernel/sem

(如man proc所说,SEMMNI是第四个字段,SEMMNS是第二个字段)。


现在,要解决您的问题“我还能使用什么?”直接,这里有一些选择:

  • 我的第一选择:使用线程。您没有显示启动其他进程的代码,但由于您在它们之间共享一个 Perl 数组,我怀疑所有进程都在运行相同的 Perl 脚本(或者代码可以那样写)。因此,不要 fork 进程,而是使用 threads并使用线程锁定原语在线程之间共享 @urls 数组。我说这是我的第一选择,因为现在多线程比线程更常见,所以有很多很好的例子,可用的模块有很多用途(而且它们通常不依赖于 Sys V接口(interface))。

  • 我的第二个选择是使用 File::Map在进程之间共享数据。这再次避免了 Sys V 接口(interface),并且可能与共享内存一样快,因为系统当然会将共享文件的页面缓存在 RAM 中(您甚至可以要求系统将文件固定到RAM,如果你愿意的话)。就像上面的线程评论一样,不要忘记使用适当的锁定。

  • 最后,我在您的代码中没有看到任何锁定调用,所以您是否有一个进程生成 URL 而其他进程以只读方式访问数据结构?如果是这样,另一种选择是通过管道将 URL 提供给子流程。但是,根据您通常拥有的 URL 数量的规模,以及如果它们真的被 children 只读,这个想法可能不适用。

希望这能为您提供一些可行的替代方案。

关于linux - 不使用共享内存的 Perl IPC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8771093/

25 4 0
文章推荐: python - 安装了 python2.7 作为备用,但默认 2.6 的路径已被破坏。默认解释器的系统路径文件?
文章推荐: javascript - 在 Knockout JS 中使用按键事件
文章推荐: javascript - 如何从 html