I don't know whats wrong with my code. I'm trying to serialize a hash inside the parent and pipe it to the fork, where it should be deserialized.
#!/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;
... produces the following error:
Can't use an undefined value as a HASH reference at ./fork_serialize.pl line 14, <GEN0> line 1.
Is there something wrong with the pipe? It seems that thaw
doesn't deserialize the retrieved scalar value. Maybe the retrieved scalar value isn't correct.
I've tried to do some semilar things without forking or piping, and its working:
#!/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";
Not much of a logical difference, he? It would be nice if anyone can explain me more of this behavior.
The trouble is that you're trying to use a line-based protocol (appending the
"\n"
on the write side, using<>
andchomp
on the read side) but your data is not text and can contain its own"\n"
s so your reader stops at the first one and chops it off.You need to use some other method of signaling the end of the serialized data, for example you could close the pipe on the write end and keep going until EOF on the read end. In fact,
Storable
has a pair of functions designed for this exact situation:store_fd
andfd_retrieve
. They'll do the transfer in a way that detects the end without an EOF, so you can keep the pipe open for more transfers.Here's a version of the guts of your program using the
fd
functions fromStorable
: