当子进程和父进程在 Perl 中写入同一个日志文件时进程卡住(在 Windows 中)

Posted

技术标签:

【中文标题】当子进程和父进程在 Perl 中写入同一个日志文件时进程卡住(在 Windows 中)【英文标题】:Process getting stuck (in windows) while child and parent are writing to the same log file in Perl 【发布时间】:2021-09-23 13:45:23 【问题描述】:

使用 Perl 执行 fork() 时,创建的子进程和父进程正在写入同一个日志文件,因此,脚本会卡在 windows 中。

我希望子进程写入不同的日志文件,而父进程写入不同的日志文件,这样就不会出现由于两个进程同时写入同一个文件而导致卡住的问题。

脚本代码sn-p:

print "I am parent process";
my $var2=&run_sleep();
print " I am out of subroutine";
print "I want to write in different log file";  


sub run_sleep                                                                                            
    print "Before fork, parent ID === script ID, i.e $scriptPid \n";
    my $pid = fork(); 
    return $pid if $pid;     # returns to the parent process(out of function) 
    print "Running child process\n";   # Proceeds for the child process
    print "I am child";
    print "PID of child process is $pid\n";
    &function_2();
    &function_3();
    print "I have finished all functions; ending child";


在这里,我希望所有子进程的打印语句(在 fork 之后)和子进程执行的所有语句(函数)都应该记录在不同的文件中,而父进程的日志应该在不同的日志文件中。 [适用于 Windows]

对于Linux,我尝试了如下的“选择”功能,并且成功了。但是,在 Windows 中,它不起作用。

use feature qw/say/;
use autodie;


# copy STDOUT to another filehandle
open (my $STDOLD, '>&', STDOUT);

# redirect STDOUT to log.txt
open (STDOUT, '>>', 'log.txt');
say 'This should be logged.';

# restore STDOUT
open (STDOUT, '>&', $STDOLD);

say 'This should show in the terminal';

【问题讨论】:

不知道它是否相关,但您可能不应该让子进程从run_sleep 返回。在末尾添加exit(0); "my $var2=&run_sleep();" 调用子例程时,子名前不必加&,见perlsub更多信息 “创建的子进程和父进程正在写入同一个日志文件” 您显示的代码未向日志文件显示任何输出语句。请说明如何写入日志文件。 不能因为写入文件/文件而“卡住”(而且你没有说它是如何/在哪里“卡住”的)。我希望问题出在代码中的其他地方,此处未显示。 【参考方案1】:

Windows 不支持分叉。 Perl 提供的最简单的 fork 仿真创建了一个线程。由于只有一个进程,因此更改 STDOUT 会影响“父”和“叉”。您将需要一种不同的方法。

【讨论】:

以上是关于当子进程和父进程在 Perl 中写入同一个日志文件时进程卡住(在 Windows 中)的主要内容,如果未能解决你的问题,请参考以下文章

(疑问)进程控制---vfork 函数

如何在 Perl 中读取和写入大缓冲区到进程 stdin/stdout/stderr?

在文件中写入打印日志时,Python子进程在屏幕缓冲区中延迟

如何优化多个进程尝试写入同一个日志文件的过程

如何清理僵尸进程(转载)

基于多进程的网络聊天程序