5

子のファイルハンドルにデータを書き込む必要があります。ファイル ハンドルは、フォークする前に親で作成されました。これは、fork がファイル ハンドルを保持し、存在する場合はそれらをロックし、親と子の間で共有されるため、親のファイル ハンドルからデータを読み取ることができるためです。これは、Linux プラットフォームと Windows プラットフォームの両方で動作する親子でデータを共有するためです。Linux で IPC::Shareable を使用してデータ共有を行うことができましたが、Windows では semaphore.pm が利用できないため、これは Windows では機能しません [windos は semaphore.pm をサポートしていません]。私のperlコンパイラをクラッシュさせていました。

したがって、ファイル ハンドル アプローチでは、子で IO 書き込みが発生しません。以下のコードを見てください


use strict;
use warnings;

print "creating file\n"; 
open FH, ">testfile.txt" or die "cant open file: $!\n";
close FH;

my $pid = fork();

if ( $pid == 0 )
{
print "entering in to child and opening file for write\n";
open FH, ">>testfile.txt" or die "cant open file: $!\n";
print FH "dummy data\n";
print FH "dummy data\n";     
print "child sleeping for 5 sec before exiting\n";
sleep 50;
exit;

}
else
{
print "entering the parent process\n";   
open FH, "<testfile.txt" or die "cant open file: $!\n";
 print <FH>;
 print <FH>;


}

4

3 に答える 3

0

mpapec が言うように、子がファイルから読み取る前に親がファイルから読み取る競合状態の影響を受けやすくなります。子プロセスがゆっくりと出力を生成し、親がそれを比較的迅速に処理することを意図している場合、親は頻繁にファイルの終わりを超えて読み取ります。seekファイルの終わりマーカーをリセットし、さらに入力を待つために使用する方法を学びたいと思うでしょう:

# parent process, after fork
sleep 1;         # give child time to create, write to file
open my $fh, '<', 'testfile.txt';
while (1) {

    my $line = <$fh>;
    if (defined($line)) {
        print $line;       # or  process($line)

        # another way (other than waitpid, see below) to see if the child is
        # finished is to use some convention between parent and child,
        # like having the child print "DONE!\n" as the last output it produces
        last if $line eq "DONE!\n";

    } else {

        # parent is starved for input. Is the child finished or is it just slow?
        use POSIX ':sys_wait_h';
        my $wpid = waitpid $pid, &WNOHANG;
        if ($wpid == $pid) {
            # child process has exited
            last;
        } else {
            # child is just slow. Clear the eof on $fh
            sleep 1;
            seek $fh, 0, 1;
        }
    }
}
close $fh;

もう 1 つすべきことは、子プロセスで出力をフラッシュすることです。大量の出力を非常に迅速に生成しない限り、出力はバッファ内で時間を費やし、親からアクセスできなくなります。

if ( $pid == 0 ) {
  print "entering in to child and opening file for write\n";
  open my $fh, ">>", "testfile.txt" or die "cant open file: $!\n";

  $fh->autoflush(1);          # force OS to send output to disk right away

  print $fh "dummy data\n";
  print $fh "dummy data\n";

  print "child sleeping for 5 sec before exiting\n";
  sleep 5.0;
  # print $fh "DONE!\n";
  close $fh;
  exit;
}

プロセス間通信は、正しく理解するのが非常に難しいものですが、非常に強力でもあります。練習を続けてください。

于 2013-11-06T16:37:47.507 に答える