我是否有可能从CGI脚本中生成像进程这样的分离守护进程 将读取的文本文件存储在内存中,然后在下一个cgi执行中重新访问内存,使用管道读取数据?
大多数托管ISP的,是否允许分离进程?内存管道是否快速,并且易于在unix / linux系统上编码/工作?
是否有解决方案可以在不使用任何额外CPAN模块的情况下完成?这是一个CGI流程,因此我希望将其保持在最低限度。
答案 0 :(得分:1)
如果您绝对希望文件的内容存在于内存中,则更简单的解决方案是创建RAM磁盘并将其存储在那里。然后你不必对cgi脚本做任何特殊的事情。
答案 1 :(得分:0)
假设你有一个简单的resource.cgi
:
#! /usr/bin/perl
use warnings;
use strict;
use Reader;
use CGI qw/ :standard /;
print header("text/plain"),
"Contents:\n",
Reader::data,
"-" x 40, "\n";
它的输出是
Content-Type: text/plain; charset=ISO-8859-1 Contents: This is a data file with some very interesting bits. ----------------------------------------
有趣的部分在Reader.pm
,从熟悉的样板开始:
package Reader;
use warnings;
use strict;
use Fcntl qw/ :DEFAULT :flock :seek /;
use POSIX qw/ setsid /;
接下来,它定义了集合点:
my $PIDFILE = "/tmp/reader.pid";
my $DATA = "/tmp/file.dat";
my $PIPE = "/tmp/reader.pipe";
子import
is called as part of use Module
。如果守护程序已在运行,则无需执行任何操作。否则,我们将守护进程分叉并将其进程ID写入$PIDFILE
。
sub import {
return unless my $fh = take_lock();
my $child = fork;
die "$0: fork: $!" unless defined $child;
if ($child) {
print $fh "$child\n" or die "$0: write $PIDFILE: $!";
close $fh or die "$0: close $PIDFILE: $!";
return;
}
# daemonize
close $fh;
chdir "/";
open STDIN, "<", "/dev/null";
open STDOUT, ">", "/dev/null";
open STDERR, ">", "/dev/null";
setsid;
open $fh, "<", $DATA or die;
undef $/;
my $data = <$fh>;
close $fh;
while (1) {
open my $fh, ">", $PIPE or die;
print $fh $data or die;
close $fh;
}
}
每个客户都需要等待$PIDFILE
锁定。一旦我们获得了锁,我们就会检查所识别的进程是否仍在运行,并在必要时创建命名管道。
sub take_lock {
sysopen my $fh, $PIDFILE, O_RDWR | O_CREAT or die "$0: open $PIDFILE: $!";
flock $fh => LOCK_EX or die "$0: flock $PIDFILE: $!";
my $pid = <$fh>;
if (defined $pid) {
chomp $pid;
if (kill 0 => $pid) {
close $fh;
return;
}
}
else {
die "$0: readline $PIDFILE: $!" if $!;
}
sysseek $fh, 0, SEEK_SET or die "$0: sysseek $PIDFILE: $!";
truncate $fh, 0 or die "$0: truncate $PIDFILE: $!";
unless (-p $PIPE) {
system("mknod", $PIPE, "p") == 0
or die "$0: mknod exited " . ($? >> 8);
}
$fh;
}
最后,阅读管道是微不足道的:
sub data {
open my $fh, "<", $DATA or die "$0: open $DATA: $!";
local $/;
scalar <$fh>;
}
不要忘记从模块中返回一个真值:
1;
您会注意到守护程序中的操作仍然可能失败。为了您的理智,您需要以某种方式记录事件,而不是默默地窒息。
关于主机是否允许长时间运行的进程,这将因提供程序而异,但即使您的守护程序不时被终止,上面的代码也会根据需要重新启动。
答案 2 :(得分:0)
你为什么要这样做?你想解决什么问题?像File::Map之类的东西会起作用吗?它是mmap文件,因此文件不在内存中,但它们就像它们一样。我在Memory-map files instead of slurping them中写了一些相关内容。