Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是Perl技术来分离独立运行的部分代码?_Perl_Process_Fork - Fatal编程技术网

什么是Perl技术来分离独立运行的部分代码?

什么是Perl技术来分离独立运行的部分代码?,perl,process,fork,Perl,Process,Fork,我没有涉及到接近操作系统的编程技术,但正如我所知,当涉及到在Perl中并行执行某些操作时,选择的武器是fork,可能还有一些基于它构建的有用模块。fork的文档页面显示: Does a fork(2) system call to create a new process running the same program at the same point. 因此,拥有一个消耗大量内存的大型应用程序,并为一个小任务调用fork,意味着将有两个大型perl进程,而第二个进程将浪费资源,只做一些简

我没有涉及到接近操作系统的编程技术,但正如我所知,当涉及到在Perl中并行执行某些操作时,选择的武器是
fork
,可能还有一些基于它构建的有用模块。
fork
的文档页面显示:

Does a fork(2) system call to create a new process running the same program at the same point.
因此,拥有一个消耗大量内存的大型应用程序,并为一个小任务调用
fork
,意味着将有两个大型perl进程,而第二个进程将浪费资源,只做一些简单的工作

因此,问题是:如何做(或者如何使用
fork
,如果它是唯一的方法),以使代码的分离部分独立运行并且仅消耗它所需的资源

这只是一个非常简单的例子:

    use strict;
    use warnings;

    my @big_array = ( 1 .. 2000000 );  # at least 80 MB memory
    sleep 10;  # to have time to inspect easely the memory usage

    fork();
    sleep 10;  # to have time to inspect easely the memory usage
子进程也消耗了80+MB


需要明确的是:与这个分离的代码进行通信或以某种方式使用它的结果并不重要,只是可以说“嘿,在后台为我运行这个简单的任务,让我同时继续我的繁重工作……不要浪费我的资源!”运行繁重的perl应用程序时。

没有办法只留下进程占用空间的一个子集,因此通常的解决方法归结为:

  • fork
    在父进程中运行内存密集型代码之前
  • 使用
    system
    打开句柄“|-”,…
    启动单独的进程。当然,这个新进程不会从其父进程继承任何数据,因此您需要以某种方式将数据传递给这个子进程

  • 您的分叉进程实际上没有使用80MB的驻留内存。该内存的很大一部分将共享-“借用”父进程,直到父进程或子进程写入该进程,此时写时复制语义将导致实际复制内存

    如果您想完全放下行李,请在您的叉子中运行
    exec
    。这将用不同的可执行文件替换子Perl进程,从而释放内存。如果您不需要与家长进行任何沟通,这也非常完美。

    fork()
    to
    exec()
    是您的小兔子。您可以使用
    fork()
    创建一个新进程(这是一个相当便宜的操作,请参见下文),然后使用
    exec()
    替换运行中的大型
    perl
    。这看起来像这样:

    use strict;
    use warnings;
    use 5.010;
    
    my @ary = (1 .. 10_000_000);
    
    if (my $pid = fork()) {
        # parent
        say "Forked $pid from $$; sleeping";
        sleep 1_000;
    } else {
        # child
        exec('perl -e sleep 1_000');
    }
    
    @ary
    只是用来填充原始进程的内存。)

    我说过,
    fork()
    ing相对便宜,尽管它复制了整个原始过程。这些说法没有冲突;设计
    fork
    的人也注意到了同样的问题。复制是惰性的,也就是说,只复制实际更改的位

    如果你发现你想让进程彼此对话,你将开始进入更复杂的IPC领域,关于这个领域已经有很多书写过了。

    fork()
    在大多数操作系统上实现是非常有效的。它通常使用一种称为“写时复制”的技术,这意味着页面最初是共享的,直到一个或另一个进程写入页面。另外,很多进程内存都将是只读映射文件


    仅仅因为一个进程在
    fork()之前使用80MB,并不意味着之后两个进程将使用160 MB。首先,在每个进程开始弄脏更多页面之前,它只会超过80MB的一小部分。

    子进程将继承其父进程的所有属性。我认为没有真正的方法可以通过分叉来解决这个问题。使用
    fork
    不是强制性的。任何技术都是可以接受的,甚至调用
    system
    。不确定词法变量是否共享。当两个进程都在运行时,我在
    ps
    的RES/SHR列中得到了这些值:48m/1776和46m/156(1M数组元素)。对不起,它应该是
    top
    而不是上面注释中的
    ps
    ,在调用
    exec()之前,它不会在很短的时间内复制内存吗
    然后在子进程终止后释放内存?毕竟,如果一切都收敛于调用system/exec,那么甚至不需要使用fork:)。。好的,对于
    exec
    它是必需的,但是
    system(“…&”)似乎可以完成这项工作well@ArtM如上所述,这是一个懒惰的副本。和<代码>系统('.&…)是<代码> FoK())/>代码>后面是“代码>执行”(<)>代码>,外壳被夹在中间只是为了咧嘴笑,还有一点脆弱性。做这件事的方法不止一种;在Linux上,PID>1的每个进程都是通过fork(最初是init)创建的。例如,如果您在终端中运行某个东西,bash(或其他什么)将分叉来执行它。写时复制语义确保这是有效的。我认为应该等到至少一个进程开始脏化。。。或smth逻辑上等同于此。这个
    my@big=(1..1000000)
    只是一个简单的通用示例代码,它可能会更复杂,并扩展到整个代码空间。谢谢你的介入。