2

私のコードの何が問題なのかわかりません。親内のハッシュをシリアル化し、それをフォークにパイプして、逆シリアル化する必要があります。

#!/usr/bin/perl
use strict;
use warnings;
use Storable qw(freeze thaw);
use IO::Pipe;

my $pipe_to_fork = IO::Pipe->new();

my $fork = fork;
if ($fork == 0) { # actual fork scope
  $pipe_to_fork->reader();
  my $hash_serialized = <$pipe_to_fork>; # wait and retrieve the serialized hash from parent
  chomp $hash_serialized;
  my %hash_rebuild = %{thaw($hash_serialized)}; # deserialize the retrieved serialized hash
  exit;
}

my %hash = ('key1' => "val1", 'key2' => "val2");

$pipe_to_fork->writer();
$pipe_to_fork->autoflush(1);

my $hash_serialized = freeze(\%hash); # serialize the hash
print $pipe_to_fork $hash_serialized."\n";
sleep 5;

exit;

... 次のエラーが発生します。

Can't use an undefined value as a HASH reference at ./fork_serialize.pl line 14, <GEN0> line 1.

パイプに何か問題がありますか?thaw取得したスカラー値を逆シリアル化していないようです。取得したスカラー値が正しくない可能性があります。

私は、フォークやパイピングをせずにいくつかのセミラルなことをしようとしましたが、その作業は次のとおりです。

#!/usr/bin/perl
use strict;
use warnings;
use Storable qw(freeze thaw);

my %hash = ('key1' => "value1", 'key2' => "value2");
my $hash_serialized = freeze(\%hash);
my %hash_rebuild = %{thaw($hash_serialized)};

print $hash_rebuild{'key2'}."\n";

論理的な違いはあまりありませんね。誰かが私にこの行動についてもっと説明してくれたらいいのにと思います。

4

2 に答える 2

6

問題は、行ベースのプロトコルを使用しようとしている ("\n"書き込み側に を追加し、読み取り側に<>andを使用chompする) ことですが、データはテキストではなく、独自"\n"の を含むことができるため、リーダーは最初のプロトコルで停止しますそしてそれを切り落とします。

シリアル化されたデータの終了を通知する他の方法を使用する必要があります。たとえば、書き込み側でパイプを閉じ、読み取り側で EOF まで続行できます。実際、 にStorableは、まさにこの状況向けに設計された関数のペアがあります:store_fdfd_retrieve. 彼らは EOF なしで終了を検出する方法で転送を行うので、より多くの転送のためにパイプを開いたままにしておくことができます。

fdの関数を使用したプログラムの内容のバージョンを次に示しますStorable

if ($fork == 0) { # actual fork scope
  $pipe_to_fork->reader();
  my %hash_rebuild = %{fd_retrieve($pipe_to_fork)}; # deserialize the retrieved serialized hash
  use Data::Dumper;$Data::Dumper::Useqq=1;print Dumper \%hash_rebuild;
  exit;
}

my %hash = ('key1' => "val1", 'key2' => "val2");

$pipe_to_fork->writer();
$pipe_to_fork->autoflush(1);

store_fd(\%hash, $pipe_to_fork);
于 2013-11-04T13:01:00.210 に答える
4

freezed問題は、ハッシュが1 行であると想定していることです。ただし、常にそうであるとは限りません。$hash_serialized複数の を含む文字列になる可能性があるため\nです。

したがって、子側で 1 行だけを読み取るのではなく、EOF まで読み取り、すべての行を連結する必要があります。

#!/usr/bin/perl
use strict;
use warnings;
use Storable qw(freeze thaw);
use IO::Pipe;

my $pipe_to_fork = IO::Pipe->new();

my $fork = fork;
if ($fork == 0) { # actual fork scope
  $pipe_to_fork->reader();
  my $hash_serialized;
  $hash_serialized .= $_ while (<$pipe_to_fork>);
  my %hash_rebuild = %{thaw($hash_serialized)}; # deserialize the retrieved serialized hash
  print $hash_rebuild{key1};
  exit;
}

my %hash = ('key1' => "val1", 'key2' => "val2");

$pipe_to_fork->writer();
$pipe_to_fork->autoflush(1);

my $hash_serialized = freeze(\%hash); # serialize the hash
print $pipe_to_fork $hash_serialized;

exit;

出力: val1

于 2013-11-04T13:11:53.673 に答える