如何在不同的脚本中使用 Perl 进行 fork?

发布于 2024-09-30 06:56:20 字数 284 浏览 4 评论 0原文

我在 Perl 中有一个进程,它使用系统命令创建另一个进程,我将其保留在内存中,并传递一些如下变量:


my $var1 = "Hello";
my $var1 = "World";
system "./another_process.pl $var1 $var2 &";

但系统命令仅返回结果,我需要获取 PID 。我想做一些像fork这样的东西。我应该怎么办?我怎样才能用不同的脚本制作类似 fork 的东西?

提前致谢!

I have a process in Perl that creates another one with the system command, I leave it on memory and I pass some variables like this:


my $var1 = "Hello";
my $var1 = "World";
system "./another_process.pl $var1 $var2 &";

But the system command only returns the result, I need to get the PID. I want to make something like fork. What should I do? How can I make something like fork but in diferent scripts?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

野の 2024-10-07 06:56:20

Perl 有一个 fork 函数。

请参阅 perldoc perlfaq8 - 如何在后台启动进程?


(由布莱恩·福伊贡献)

没有单一的方法来运行代码
在后台,所以你不必
等待它在你之前完成
程序继续执行其他任务。
流程管理取决于您
特定的操作系统,以及许多
这些技术都在 perlipc 中。
多个 CPAN 模块可能能够
帮助,包括
IPC::Open2
或者
IPC::Open3
,
IPC::Run
,
并行::作业
,
Parallel::ForkManager
,
POE
,
Proc::Background
, 和
Win32::Process

您可能还有许多其他模块
使用,所以检查这些命名空间
还有其他选择。如果您在
类 Unix 系统,你也许可以
摆脱系统调用,你
把 &在命令末尾:

 系统("cmd &")

您也可以尝试使用
fork,
如中所述
perlfunc
(尽管这与
许多模块都适合您)。

STDIN、STDOUT 和 STDERR 是共享的

主要流程和
后台进程(“子”进程)
共享相同的 STDIN、STDOUT 和
STDERR 文件句柄。如果双方都尝试
立即访问它们,奇怪的事情
可能会发生。您可能想要关闭或
为孩子重新打开这些。你可以
通过打开管道来解决这个问题
(参见 open)但在某些系统上这
意味着子进程不能
比父母活得更久。

信号

你必须捕捉到SIGCHLD
信号,也可能是 SIGPIPE。
当后台运行时发送SIGCHLD
过程结束。 SIGPIPE 发送时间
您写入其子文件句柄
进程已关闭(未捕获的
SIGPIPE 可能会导致您的程序
默默地死去)。这不是问题
system("cmd&")

僵尸

你必须做好“收获”的准备
子进程完成时。
$SIG{CHLD} = 子 { 等待 };
$SIG{CHLD} = '忽略';您还可以
使用双叉。你立即
wait() 为你的第一个孩子,并且
init 守护进程将 wait() 等待您的
一旦退出,孙子。

除非 ($pid = fork) {
        除非(叉子){ 
            exec“你真正想做的事”;
            die“执行失败!”;
  }

        退出 0;
    }

    waitpid($pid, 0);

查看信号
perlipc
有关执行此操作的其他代码示例。
僵尸不是问题
system("prog &").system("prog &").

Perl has a fork function.

See perldoc perlfaq8 - How do I start a process in the background?


(contributed by brian d foy)

There's not a single way to run code
in the background so you don't have to
wait for it to finish before your
program moves on to other tasks.
Process management depends on your
particular operating system, and many
of the techniques are in perlipc.
Several CPAN modules may be able to
help, including
IPC::Open2
or
IPC::Open3
,
IPC::Run
,
Parallel::Jobs
,
Parallel::ForkManager
,
POE
,
Proc::Background
, and
Win32::Process
.

There are many other modules you might
use, so check those namespaces for
other options too. If you are on a
Unix-like system, you might be able to
get away with a system call where you
put an & on the end of the command:

    system("cmd &")

You can also try using
fork,
as described in
perlfunc
(although this is the same thing that
many of the modules will do for you).

STDIN, STDOUT, and STDERR are shared

Both the main process and the
backgrounded one (the "child" process)
share the same STDIN, STDOUT and
STDERR filehandles. If both try to
access them at once, strange things
can happen. You may want to close or
reopen these for the child. You can
get around this with opening a pipe
(see open) but on some systems this
means that the child process cannot
outlive the parent.

Signals

You'll have to catch the SIGCHLD
signal, and possibly SIGPIPE too.
SIGCHLD is sent when the backgrounded
process finishes. SIGPIPE is sent when
you write to a filehandle whose child
process has closed (an untrapped
SIGPIPE can cause your program to
silently die). This is not an issue
with system("cmd&").

Zombies

You have to be prepared to "reap" the
child process when it finishes.
$SIG{CHLD} = sub { wait };
$SIG{CHLD} = 'IGNORE'; You can also
use a double fork. You immediately
wait() for your first child, and the
init daemon will wait() for your
grandchild once it exits.

unless ($pid = fork) {
        unless (fork) { 
            exec "what you really wanna do";
            die "exec failed!";
  }

        exit 0;
    }

    waitpid($pid, 0);

See Signals in
perlipc
for other examples of code to do this.
Zombies are not an issue with
system("prog &").system("prog &").

如梦亦如幻 2024-10-07 06:56:20

确实可以使用fork/exec,但我认为简单地使用open的管道形式会容易得多。返回值不仅是您要查找的 pid,您还可以连接到进程的 stdin 或 stdout,具体取决于您打开的方式。例如:

open my $handle, "foo|";

将返回 foo 的 pid 并将您连接到标准输出,这样如果您从 foo 获得一行输出。使用“|foo”代替将允许您写入 foo 的标准输入。

您还可以使用 open2 和 open3 同时执行这两项操作,尽管这有一些主要的注意事项,因为您可能会因 io 缓冲而遇到意外问题。

It's true that you can use fork/exec, but I think it will be much easier to simply use the pipe form of open. Not only is the return value the pid you are looking for, you can be connected to either the stdin or stdout of the process, depending on how you open. For instance:

open my $handle, "foo|";

will return the pid of foo and connect you to the stdout so that if you you get a line of output from foo. Using "|foo" instead will allow you to write to foo's stdin.

You can also use open2 and open3 to do both simultaneously, though that has some major caveats applied as you can run in to unexpected issues due to io buffering.

苯莒 2024-10-07 06:56:20

使用 fork执行

Use fork and exec.

¢蛋碎的人ぎ生 2024-10-07 06:56:20

如果您需要获取 Perl 脚本的 PID,可以使用 $$ 变量。您可以将其放入 another_process.pl 中,然后让它将 pid 输出到文件中。你能更清楚地了解like fork吗?您始终可以使用 fork exec 组合。

If you need to get the PID of a perl script you can use the $$ variable. You can put it in your another_process.pl then have it output the pid to a file. Can you be more clear on like fork? You can always use the fork exec combination.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文