gpt4 book ai didi

linux - fork() 和 STDOUT/STDERR 从子进程到控制台

转载 作者:IT王子 更新时间:2023-10-29 00:45:59 26 4
gpt4 key购买 nike

我正在编写一个 fork 多个子进程的程序,我希望所有这些子进程都能够将行写入 STDERRSTDOUT 而无需输出是乱码。我没有做任何花哨的事情,只是发出以新行结尾的行(至少在我的理解中这将是 Linux 的原子操作)。从 perlfaq 它说:

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.

它说我应该为 child “关闭或重新打开”这些文件句柄。关闭很简单,但是“重新打开”是什么意思呢?我已经在我的子进程中尝试过类似的方法,但它不起作用(输出仍然是乱码):

open(SAVED_STDERR, '>&', \*STDERR) or die "Could not create copy of STDERR: $!";
close(STDERR);

# re-open STDERR
open(STDERR, '>&SAVED_STDERR') or die "Could not re-open STDERR: $!";

那么,我做错了什么?它暗示的管道示例是什么样的?有没有更好的方法来协调多个进程的输出到控制台?

最佳答案

对于 STDOUT 和 STDIN,写入文件句柄不是是原子的。 fifos 之类的东西有特殊情况,但这不是你目前的情况。

当它说重新打开 STDOUT 时,这意味着“创建一个新的 STDOUT 实例”这个新实例与父实例不同。这就是您可以在系统上打开多个终端而不是让所有 STDOUT 都去同一个地方的方法。

管道解决方案将通过管道(如 shell 中的 |)将子级连接到父级,您需要让父级从管道中读出并多路复用输出本身。父级将负责从管道中读取数据并确保它不会同时交错管道的输出和发往父级 STDOUT 的输出。有一个例子和文章 here管道。

一个片段:

use IO::Handle;

pipe(PARENTREAD, PARENTWRITE);
pipe(CHILDREAD, CHILDWRITE);

PARENTWRITE->autoflush(1);
CHILDWRITE->autoflush(1);

if ($child = fork) { # Parent code
chomp($result = <PARENTREAD>);
print "Got a value of $result from child\n";
waitpid($child,0);
} else {
print PARENTWRITE "FROM CHILD\n";
exit;
}

看看子进程如何不写入标准输出,而是使用管道向父进程发送消息,父进程使用其标准输出进行写入。请务必看一看,因为我省略了关闭不需要的文件句柄等内容。

关于linux - fork() 和 STDOUT/STDERR 从子进程到控制台,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3876492/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com