1MCE::Shared::Handle(3)User Contributed Perl DocumentationMCE::Shared::Handle(3)
2
3
4
6 MCE::Shared::Handle - Handle helper class
7
9 This document describes MCE::Shared::Handle version 1.840
10
12 A handle helper class for use as a standalone or managed by
13 MCE::Shared.
14
16 # non-shared or local construction for use by a single process
17 # shorter, mce_open is an alias for MCE::Shared::Handle::open
18
19 use MCE::Shared::Handle;
20
21 MCE::Shared::Handle->open( my $fh, "<", "bio.fasta" )
22 or die "open error: $!";
23 MCE::Shared::Handle::open my $fh, "<", "bio.fasta"
24 or die "open error: $!";
25
26 mce_open my $fh, "<", "bio.fasta" or die "open error: $!";
27
28 # construction for sharing with other threads and processes
29 # shorter, mce_open is an alias for MCE::Shared::open
30
31 use MCE::Shared;
32
33 MCE::Shared->open( my $fh, "<", "bio.fasta" )
34 or die "open error: $!";
35 MCE::Shared::open my $fh, "<", "bio.fasta"
36 or die "open error: $!";
37
38 mce_open my $fh, "<", "bio.fasta" or die "open error: $!";
39
40 # example, output is serialized, not garbled
41
42 use MCE::Hobo;
43 use MCE::Shared;
44
45 mce_open my $ofh, ">>", \*STDOUT or die "open error: $!";
46 mce_open my $ifh, "<", "file.log" or die "open error: $!";
47
48 sub parallel {
49 $/ = "\n"; # can set the input record separator
50 while (my $line = <$ifh>) {
51 printf {$ofh} "[%5d] %s", $., $line;
52 }
53 }
54
55 MCE::Hobo->create( \¶llel ) for 1 .. 4;
56
57 $_->join() for MCE::Hobo->list();
58
59 # handle functions
60
61 my $bool = eof($ifh);
62 my $off = tell($ifh);
63 my $fd = fileno($ifh);
64 my $char = getc($ifh);
65 my $line = readline($ifh);
66
67 binmode $ifh;
68 seek $ifh, 10, 0;
69 read $ifh, my($buf), 80;
70
71 print {$ofh} "foo\n";
72 printf {$ofh} "%s\n", "bar";
73
74 open $ofh, ">>", \*STDERR;
75 syswrite $ofh, "shared handle to STDERR\n";
76
77 close $ifh;
78 close $ofh;
79
81 open ( filehandle, expr )
82 open ( filehandle, mode, expr )
83 open ( filehandle, mode, reference )
84 In version 1.007 and later, constructs a new object by opening the
85 file whose filename is given by "expr", and associates it with
86 "filehandle". When omitting error checking at the application
87 level, MCE::Shared emits a message and stop if open fails.
88
89 # non-shared or local construction for use by a single process
90
91 use MCE::Shared::Handle;
92
93 MCE::Shared::Handle->open( my $fh, "<", "file.log" ) or die "$!";
94 MCE::Shared::Handle::open my $fh, "<", "file.log" or die "$!";
95
96 mce_open my $fh, "<", "file.log" or die "$!"; # ditto
97
98 # construction for sharing with other threads and processes
99
100 use MCE::Shared;
101
102 MCE::Shared->open( my $fh, "<", "file.log" ) or die "$!";
103 MCE::Shared::open my $fh, "<", "file.log" or die "$!";
104
105 mce_open my $fh, "<", "file.log" or die "$!"; # ditto
106
107 Simple examples to open a file for reading:
108
109 # mce_open is exported by MCE::Shared or MCE::Shared::Handle.
110 # It creates a shared file handle with MCE::Shared present
111 # or a non-shared handle otherwise.
112
113 mce_open my $fh, "< input.txt" or die "open error: $!";
114 mce_open my $fh, "<", "input.txt" or die "open error: $!";
115 mce_open my $fh, "<", \*STDIN or die "open error: $!";
116
117 and for writing:
118
119 mce_open my $fh, "> output.txt" or die "open error: $!";
120 mce_open my $fh, ">", "output.txt" or die "open error: $!";
121 mce_open my $fh, ">", \*STDOUT or die "open error: $!";
122
124 Starting with "MCE::Shared" v1.007, chunk IO is possible for both non-
125 shared and shared handles. Chunk IO is enabled by the trailing 'k' or
126 'm' for read size. Also, chunk IO supports the special "\n>"-like
127 record separator. That anchors ">" at the start of the line. Workers
128 receive record(s) beginning with ">" and ending with "\n".
129
130 # non-shared handle ---------------------------------------------
131
132 use MCE::Shared::Handle;
133
134 mce_open my $fh, '<', 'bio.fasta' or die "open error: $!";
135
136 # shared handle -------------------------------------------------
137
138 use MCE::Shared;
139
140 mce_open my $fh, '<', 'bio.fasta' or die "open error: $!";
141
142 # 'k' or 'm' indicates kibiBytes (KiB) or mebiBytes (MiB) respectively.
143 # Read continues reading until reaching the record separator or EOF.
144 # Optionally, one may specify the record separator.
145
146 $/ = "\n>";
147
148 while ( read($fh, my($buf), '2k') ) {
149 print "# chunk number: $.\n";
150 print "$buf\n";
151 }
152
153 $. contains the chunk_id above or the record_number below.
154 "readline($fh)" or "<$fh"> may be used for reading a single record.
155
156 while ( my $buf = <$fh> ) {
157 print "# record number: $.\n";
158 print "$buf\n";
159 }
160
161 The following provides a parallel demonstration. Workers receive the
162 next chunk from the shared-manager process where the actual read takes
163 place. MCE::Shared also works with "threads", "forks", and likely other
164 parallel modules.
165
166 use MCE::Hobo; # (change to) use threads; (or) use forks;
167 use MCE::Shared;
168 use feature qw( say );
169
170 my $pattern = 'something';
171 my $hugefile = 'somehuge.log';
172
173 my $result = MCE::Shared->array();
174 mce_open my $fh, "<", $hugefile or die "open error: $!";
175
176 sub task {
177 # the trailing 'k' or 'm' for size enables chunk IO
178 while ( read $fh, my( $slurp_chunk ), "640k" ) {
179 my $chunk_id = $.;
180 # process chunk only if a match is found; ie. fast scan
181 # optionally, comment out the if statement and closing brace
182 if ( $slurp_chunk =~ /$pattern/m ) {
183 my @matches;
184 while ( $slurp_chunk =~ /([^\n]+\n)/mg ) {
185 my $line = $1; # save $1 to not lose the value
186 push @matches, $line if ( $line =~ /$pattern/ );
187 }
188 $result->push( @matches ) if @matches;
189 }
190 }
191 }
192
193 MCE::Hobo->create('task') for 1 .. 4;
194
195 # do something else
196
197 MCE::Hobo->waitall();
198
199 say $result->len();
200
201 For comparison, the same thing using "MCE::Flow". MCE workers read the
202 file directly when given a plain path, so will have lesser overhead.
203 However, the run time is similar if one were to pass a file handle
204 instead to mce_flow_f.
205
206 The benefit of chunk IO is from lesser IPC for the shared-manager
207 process (above). Likewise, for the mce-manager process (below).
208
209 use MCE::Flow;
210 use feature qw( say );
211
212 my $pattern = 'something';
213 my $hugefile = 'somehuge.log';
214
215 my @result = mce_flow_f {
216 max_workers => 4, chunk_size => '640k',
217 use_slurpio => 1,
218 },
219 sub {
220 my ( $mce, $slurp_ref, $chunk_id ) = @_;
221 # process chunk only if a match is found; ie. fast scan
222 # optionally, comment out the if statement and closing brace
223 if ( $$slurp_ref =~ /$pattern/m ) {
224 my @matches;
225 while ( $$slurp_ref =~ /([^\n]+\n)/mg ) {
226 my $line = $1; # save $1 to not lose the value
227 push @matches, $line if ( $line =~ /$pattern/ );
228 }
229 MCE->gather( @matches ) if @matches;
230 }
231 }, $hugefile;
232
233 say scalar( @result );
234
236 Implementation inspired by Tie::StdHandle.
237
239 Perl must have IO::FDPass for constructing a shared "condvar" or
240 "queue" while the shared-manager process is running. For platforms
241 where IO::FDPass isn't possible, construct "condvar" and "queue" before
242 other classes. On systems without "IO::FDPass", the manager process is
243 delayed until sharing other classes or started explicitly.
244
245 use MCE::Shared;
246
247 my $has_IO_FDPass = $INC{'IO/FDPass.pm'} ? 1 : 0;
248
249 my $cv = MCE::Shared->condvar();
250 my $que = MCE::Shared->queue();
251
252 MCE::Shared->start() unless $has_IO_FDPass;
253
254 Regarding mce_open, "IO::FDPass" is needed for constructing a shared-
255 handle from a non-shared handle not yet available inside the shared-
256 manager process. The workaround is to have the non-shared handle made
257 before the shared-manager is started. Passing a file by reference is
258 fine for the three STD* handles.
259
260 # The shared-manager knows of \*STDIN, \*STDOUT, \*STDERR.
261
262 mce_open my $shared_in, "<", \*STDIN; # ok
263 mce_open my $shared_out, ">>", \*STDOUT; # ok
264 mce_open my $shared_err, ">>", \*STDERR; # ok
265 mce_open my $shared_fh1, "<", "/path/to/sequence.fasta"; # ok
266 mce_open my $shared_fh2, ">>", "/path/to/results.log"; # ok
267
268 mce_open my $shared_fh, ">>", \*NON_SHARED_FH; # requires IO::FDPass
269
270 The IO::FDPass module is known to work reliably on most platforms.
271 Install 1.1 or later to rid of limitations described above.
272
273 perl -MIO::FDPass -le "print 'Cheers! Perl has IO::FDPass.'"
274
276 MCE, MCE::Hobo, MCE::Shared
277
279 Mario E. Roy, <marioeroy AT gmail DOT com>
280
281
282
283perl v5.28.1 2019-01-04 MCE::Shared::Handle(3)